ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExecGeneric.C
Go to the documentation of this file.
1 /* Copyright 2008 Lawrence Livermore National Security, LLC */
2 #include "sage3basic.h"
3 #include "checkIsModifiedFlag.h"
4 #include <algorithm>
5 #include <fstream>
6 
7 #ifndef _MSC_VER
8 // DQ (11/27/2009): This header file is not available using MSVS (Windows).
9 #include <sys/wait.h>
10 #endif
11 
13 // functions
15 
16 
19 void
21 {
22  std::ofstream f(name.c_str(), std::ios_base::out|std::ios_base::binary|std::ios_base::trunc);
23  ROSE_ASSERT(f.is_open());
24  f.exceptions(std::ios::badbit | std::ios::failbit);
25  unparseBinaryFormat(f, ef);
26  f.close();
27 }
28 
31 void
33 {
34  ROSE_ASSERT(ef);
35 
36  if (checkIsModifiedFlag(ef))
37  ef->reallocate();
38 
39  ef->unparse(f);
40 }
41 
44 {
45  SgAsmGenericFile *ef=NULL;
46  std::vector<DataConverter*> converters;
47  converters.push_back(NULL); /*no conversion*/
48  converters.push_back(new Rot13);
49 
50  try {
51  for (size_t ci=0; !ef && ci<converters.size(); ci++) {
52  ef = new SgAsmGenericFile();
53  ef->set_data_converter(converters[ci]);
54  converters[ci] = NULL;
55  ef->parse(name);
56 
58  (new SgAsmElfFileHeader(ef))->parse();
59  } else if (SgAsmDOSFileHeader::is_DOS(ef)) {
60  SgAsmDOSFileHeader *dos_hdr = new SgAsmDOSFileHeader(ef);
61  dos_hdr->parse(false); /*delay parsing the DOS Real Mode Section*/
62 
63  /* DOS Files can be overloaded to also be PE, NE, LE, or LX. Such files have an Extended DOS Header
64  * immediately after the DOS File Header (various forms of Extended DOS Header exist). The Extended DOS Header
65  * contains a file offset to a PE, NE, LE, or LX File Header, the first bytes of which are a magic number. The
66  * is_* methods check for this magic number. */
67  SgAsmGenericHeader *big_hdr = NULL;
68  if (SgAsmPEFileHeader::is_PE(ef)) {
69  SgAsmDOSExtendedHeader *dos2_hdr = new SgAsmDOSExtendedHeader(dos_hdr);
70  dos2_hdr->parse();
71  SgAsmPEFileHeader *pe_hdr = new SgAsmPEFileHeader(ef);
72  pe_hdr->set_offset(dos2_hdr->get_e_lfanew());
73  pe_hdr->parse();
74  big_hdr = pe_hdr;
75  } else if (SgAsmNEFileHeader::is_NE(ef)) {
76  SgAsmNEFileHeader::parse(dos_hdr);
77  } else if (SgAsmLEFileHeader::is_LE(ef)) { /*or LX*/
78  SgAsmLEFileHeader::parse(dos_hdr);
79  }
80 
81 #if 0 /*This iterferes with disassembling the DOS interpretation*/
82  /* Now go back and add the DOS Real-Mode section but rather than using the size specified in the DOS header,
83  * constrain it to not extend beyond the beginning of the PE, NE, LE, or LX file header. This makes detecting
84  * holes in the PE format much easier. */
85  dos_hdr->parse_rm_section(big_hdr ? big_hdr->get_offset() : 0);
86 #else
87  dos_hdr->parse_rm_section(0);
88 #endif
89  } else {
90  if (ef) delete ef->get_data_converter();
91  SageInterface::deleteAST(ef); /* ~SgAsmGenericFile() closes ef->p_fd if it was opened. */
92  ef = NULL;
93  }
94  }
95  } catch(...) {
96  for (size_t ci=0; ci<converters.size(); ci++)
97  delete converters[ci];
98  if (ef) delete ef->get_data_converter();
100  ef = NULL;
101  throw;
102  }
103 
104  /* If no executable file could be parsed then try to use system tools to get the file type. On Unix-based systems, the
105  * "file" command does a thorough job of trying to figure out the type of file. If we can't figure out the file name then
106  * just throw some generic error. */
107  if (!ef) {
108  /* Use file(1) to try to figure out the file type to report in the exception */
109  int child_stdout[2];
110 #ifdef _MSC_VER
111 #pragma message ("WARNING: Commented out use of functions from sys/wait.h")
112  printf ("ERROR: Commented out use of functions from sys/wait.h \n");
113  ROSE_ASSERT(false);
114 #else
115  pipe(child_stdout);
116  pid_t pid = fork();
117  if (0==pid) {
118  close(0);
119  dup2(child_stdout[1], 1);
120  close(child_stdout[0]);
121  close(child_stdout[1]);
122  execlp("file", "file", "-b", name, NULL);
123  exit(1);
124  } else if (pid>0) {
125  char buf[4096];
126  memset(buf, 0, sizeof buf);
127  read(child_stdout[0], buf, sizeof buf);
128  buf[sizeof(buf)-1] = '\0';
129  if (char *nl = strchr(buf, '\n')) *nl = '\0'; /*keep only first line w/o LF*/
130  waitpid(pid, NULL, 0);
131  char mesg[64+sizeof buf];
132  sprintf(mesg, "unrecognized file format: %s", buf);
133  throw FormatError(mesg);
134  } else {
135  throw FormatError("unrecognized file format");
136  }
137 #endif
138  }
139 
140  ef->set_tracking_references(false); /*all done parsing*/
141 
142  /* Is the file large enough to hold all sections? If any section extends past the EOF then set truncate_zeros, which will
143  * cause the unparser to not write zero bytes to the end of the file. */
145 
146  /* If any section is the target of a function symbol then mark that section as containing code even if that section is not
147  * memory mapped with execute permission. */
148 
149 #ifndef USE_ROSE
150  // DQ (1/27/2010): This is a problem for ROSE compiling this file.
151  struct: public AstSimpleProcessing {
152  void visit(SgNode *node) {
154  if (symbol && symbol->get_type()==SgAsmGenericSymbol::SYM_FUNC) {
155  SgAsmGenericSection *section = symbol->get_bound();
156  if (section)
157  section->set_contains_code(true);
158  }
159  }
160  } t1;
161  t1.traverse(ef, preorder);
162 #endif
163 
164  return ef;
165 }
167 {
168  return isa_to_string(isa);
169 }
170 
172 {
173  switch(isa & ISA_FAMILY_MASK){
174  case ISA_IA32_Family: return "Intel x86"; /* x86 IA-32 family of architectures; Intel, AMD, VIA, ... */
175  case ISA_X8664_Family: return "x86-64"; /* x86-64 family of architectures: Intel, AMD, VIA, ... */
176  case ISA_SPARC_Family: return "SPARC"; /* SPARC family of architectures; Sun Microsystems */
177  case ISA_M68K_Family: return "Motorola m68k"; /* Motorala m68k family */
178  case ISA_M88K_Family: return "Motorola m88k"; /* Motorola m88k family (not very popular) */
179  case ISA_MIPS_Family: return "MIPS"; /* 32/64-bit RISC; MIPS Technologies, Inc. */
180  case ISA_I860_Family: return "Intel i860"; /* Intel i860 family; 1989-mid 90's; RISC VLIW */
181  case ISA_IA64_Family: return "Itanium"; /* Intel 64-bit architecture */
182  case ISA_ARM_Family: return "ARM"; /* Acorn RISC Machine, Advanced RISC Machines, ARM Limited */
183  case ISA_OTHER_Family:
184  switch(isa){
185  case ISA_PowerPC:
186  case ISA_PowerPC_64bit: return "PowerPC";
187  default:
188  return "Other Family";
189  };
190  default:
191  break;
192  };
193  char buf[64];
194  snprintf(buf,sizeof(buf),"unknown isa family (%zu)",size_t(isa & ISA_FAMILY_MASK)) ;
195  return buf;
196 }
197 
198 
200 {
201 
202  switch(isa){
203  case ISA_UNSPECIFIED: return "ISA_UNSPECIFIED"; /* File does not specify an architecture */
204  case ISA_OTHER: return "ISA_OTHER"; /* Architecture is something other than below */
205  case ISA_FAMILY_MASK: return "ISA_FAMILY_MASK";
206  case ISA_IA32_286: return "IA32_286"; /* 80286 */
207  case ISA_IA32_386: return "IA32_386"; /* MMU with paging */
208  case ISA_IA32_486: return "IA32_486"; /* risc-like pipelining, integrated FPU, on-chip cache */
209  case ISA_IA32_Pentium: return "IA32_Pentium"; /* superscalar, 64-bit databus, MMX */
210  case ISA_IA32_Cyrix6x86: return "IA32_Cyrix6x86"; /* register renaming, speculative execution */
211  case ISA_IA32_AMDK5: return "IA32_AMDK5"; /* micro-op translation */
212  case ISA_IA32_PentiumPro: return "IA32_PentiumPro"; /* PAE, integrated L2 cache */
213  case ISA_IA32_PentiumII: return "IA32_PentiumII"; /* L3-cache, 3D Now, SSE */
214  case ISA_IA32_Athlon: return "IA32_Athlon"; /* superscalar FPU, wide design */
215  case ISA_IA32_Pentium4: return "IA32_Pentium4"; /* deeply pipelined, high frequency, SSE2, hyper-threading */
216  case ISA_IA32_PentiumM: return "IA32_PentiumM"; /* low power */
217 
218  case ISA_X8664_Athlon64: return "X8664_Athlon64"; /* on-die memory controller, 40-bit phys address space */
219  case ISA_X8664_Prescott: return "X8664_Prescott"; /* deeply pipelined, high frequency, SSE3 */
220  case ISA_X8664_IntelCore: return "X8664_IntelCore"; /* low power, multi-core, lower clock frequency */
221  case ISA_X8664_AMDPhenom: return "X8664_AMDPhenom"; /* quad core, 128-bit FPUs, SSE4a, native mem ctrl, on-die L3 cache */
222 
223  case ISA_SPARC_V7: return "SPARC_V7";
224  case ISA_SPARC_V8: return "SPARC_V8";
225  case ISA_SPARC_V8E: return "SPARC_V8E";
226  case ISA_SPARC_V9: return "SPARC_V9";
227  case ISA_SPARC_V9JPS1: return "SPARC_V9JPS1";
228  case ISA_SPARC_V9UA: return "SPARC_V9UA";
229  case ISA_SPARC_V9JPS2: return "SPARC_V9JPS2";
230 
231  case ISA_M68K_68000: return "M68K_68000"; /* generation one: 16/32 internal; 8-, 16-, 32-bit interface */
232  case ISA_M68K_68EC000: return "M68K_68EC000";
233  case ISA_M68K_68HC000: return "M68K_68HC000";
234  case ISA_M68K_68008: return "M68K_68008";
235  case ISA_M68K_68010: return "M68K_68010";
236  case ISA_M68K_68012: return "M68K_68012";
237  case ISA_M68K_68020: return "M68K_68020"; /* generation two: fully 32-bit */
238  case ISA_M68K_68EC020: return "M68K_68EC020";
239  case ISA_M68K_68030: return "M68K_68030";
240  case ISA_M68K_68EC030: return "M68K_68EC030";
241  case ISA_M68K_68040: return "M68K_68040"; /* generation three: pipelined */
242  case ISA_M68K_68EC040: return "M68K_68EC040";
243  case ISA_M68K_68LC040: return "M68K_68LC040";
244  case ISA_M68K_68060: return "M68K_68060"; /* generation four: superscalar */
245  case ISA_M68K_ColdFire: return "M68K_ColdFire"; /* other */
246  case ISA_M68K_DragonBall: return "M68K_DragonBall"; /* other */
247 
248  case ISA_M88K_88100: return "M88K_88100"; /* 32-bit, integrated FPU mated with 88200 MMU and cache controller */
249  case ISA_M88K_88110: return "M88K_88110"; /* single package of 88100+88200 */
250  case ISA_M88K_88110MP: return "M88K_88110MP"; /* on-chip comm for use in multi-processor systems */
251  case ISA_M88K_88120: return "M88K_88120"; /* superscalar (never actually released) */
252 
253 
254  case ISA_MIPS_MarkI: return "MIPS_MarkI"; /* R2000, R3000 */
255  case ISA_MIPS_MarkII: return "MIPS_MarkII"; /* R6000 */
256  case ISA_MIPS_MarkIII: return "MIPS_MarkIII"; /* R4000 */
257  case ISA_MIPS_R2000: return "MIPS_R2000"; /* 32-bit, Big or little endian */
258  case ISA_MIPS_R3000: return "MIPS_R3000"; /* virtual identical: Pacempi's R3400, IDT's R3500, Toshiba R3900 */
259  case ISA_MIPS_R4000: return "MIPS_R4000"; /* 64-bit; others in the series had larger caches and bug fixes */
260  case ISA_MIPS_R4200: return "MIPS_R4200"; /* low-cost version of R4000 */
261  case ISA_MIPS_R4300: return "MIPS_R4300"; /* low-cost version of R4000 with 32-bit external bus */
262  case ISA_MIPS_R4600: return "MIPS_R4600"; /* "Orion" by Qauntum Effect Devices (QED); larger caches */
263  case ISA_MIPS_R4650: return "MIPS_R4650"; /* by QED */
264  case ISA_MIPS_R4700: return "MIPS_R4700"; /* "Orion" by QED */
265  case ISA_MIPS_R5000: return "MIPS_R5000"; /* by QED */
266  case ISA_MIPS_RM7000: return "MIPS_RM7000"; /* by PMC-Sierra; 256kB L2 and optional L3 */
267  case ISA_MIPS_R8000: return "MIPS_R8000"; /* superscalar, fairly rare */
268  case ISA_MIPS_R10000: return "MIPS_R10000"; /* R8000 on a single chip; 32kB caches; out-of-order */
269  case ISA_MIPS_R12000: return "MIPS_R12000"; /* R10000 + higher clock rates */
270  case ISA_MIPS_R14000: return "MIPS_R14000"; /* R12000 + support for DDR SRAM; 200MHz front side bus */
271  case ISA_MIPS_R16000: return "MIPS_R16000"; /* R14000 + increased freq, more L1, smaller die */
272  case ISA_MIPS_R16000A: return "MIPS_R16000A";
273  case ISA_MIPS_16: return "MIPS_16"; /* Unknown. Windows PE architecture 0x266 "MIPS16" */
274  case ISA_MIPS_FPU: return "MIPS_FPU"; /* Unknown. Windows PE architecture 0x366 "MIPS with FPU" */
275  case ISA_MIPS_16FPU: return "MIPS_16FPU"; /* Unknown. Windows PE architecture 0x466 "MIPS16 with FPU" */
276 
277  case ISA_I860_860XR: return "I860_860XR"; /* (code named N10) 25-40MHz */
278  case ISA_I860_860XP: return "I860_860XP"; /* (code named N11) larger caches; 40-50MHz; same IS as XR */
279 
280  case ISA_IA64_Itanium: return "IA64_Itanium"; /* First generation */
281  case ISA_IA64_Itanium2: return "IA64_Itanium2"; /* Second generation starting Nov 2007 */
282 
283  /* See http://en.wikipedia.org/wiki/ARM_architecture */
284  case ISA_ARM_ARM1: return "ARM1"; /* ARM evaluation system */
285  case ISA_ARM_ARM2: return "ARM2"; /* ARM2, ARM250 cores */
286  case ISA_ARM_ARM3: return "ARM3"; /* ARM2a core */
287  case ISA_ARM_ARM6: return "ARM6"; /* ARM60, ARM600, ARM610 cores */
288  case ISA_ARM_ARM7: return "ARM7"; /* ARM{700,710,710a,7100,7500,7500FE} cores */
289  case ISA_ARM_ARM7TDMI: return "ARM7TDMI"; /* ARM{7TDMI,7TDMI-S,710T,720T,740T,7EJ-S} cores */
290  case ISA_ARM_StrongARM: return "StrongARM"; /* SA-110, SA-1110 cores */
291  case ISA_ARM_ARM8: return "ARM8"; /* ARM810 core */
292  case ISA_ARM_ARM9TDMI: return "ARM9TDMI"; /* ARM{9TDMI,920T,922T,940T} cores */
293  case ISA_ARM_ARM9E: return "ARM9E"; /* ARM{946E-S,966E-S,968E-S,926EJ-S,966HS} cores */
294  case ISA_ARM_ARM10E: return "ARM10E"; /* ARM{1020E,1022E,1026EJ-S} cores */
295  case ISA_ARM_XScale: return "ARM_XScale"; /* 80200, IOP310, IOP315, 80219, IOP321, IOP33x, IOP34x, PXA210,
296  * PXA250, PXA255, PXA26x, PXA27x, PXA800(E)F, Monahans, PXA900,
297  * IXC1100, IXP2400, IXP2800, IXP2850, IXP2325, IXP2350, IXP42x,
298  * IXP460, IXP465 cores */
299  case ISA_ARM_ARM11: return "ARM11"; /* ARMv{6,6T2,6KZ,6K} cores */
300  case ISA_ARM_Cortex: return "ARM_Cortex"; /* Cortex-{A8,A9,A9 MPCore,R4(F),M3,M1} cores */
301 
302  /* Others, not yet incorporated into this enum */
303  case ISA_ATT_WE_32100: return "ATT_WE_32100"; /* sometimes simply "M32" */
304  case ISA_IBM_System_370: return "IBM_System_370";
305  case ISA_HPPA: return "HPPA";
306  case ISA_Fujitsu_VPP500: return "Fujitsu_VPP500";
307  case ISA_Sun_v8plus: return "Sun_v8plus";
308  case ISA_PowerPC: return "PowerPC";
309  case ISA_PowerPC_64bit: return "PowerPC_64bit";
310  case ISA_IBM_S390: return "IBM_S390";
311  case ISA_NEC_V800_series: return "NEC_V800_series";
312  case ISA_Fujitsu_FR20: return "Fujitsu_FR20";
313  case ISA_TRW_RH_32: return "TRW_RH_32";
314  case ISA_Motorola_RCE: return "Motorola_RCE";
315  case ISA_Digital_Alpha_fake: return "Digital_Alpha_fake";
316  case ISA_Hitachi_SH: return "Hitachi_SH";
317  case ISA_Siemens_Tricore: return "Siemens_Tricore";
318  case ISA_Argonaut_RISC_Core: return "Argonaut_RISC_Core";
319  case ISA_Hitachi_H8_300: return "Hitachi_H8_300";
320  case ISA_Hitachi_H8_300H: return "Hitachi_H8_300H";
321  case ISA_Hitachi_H8S: return "Hitachi_H8S";
322  case ISA_Hitachi_H8_500: return "Hitachi_H8_500";
323  case ISA_Stanford_MIPS_X: return "Stanford_MIPS_X";
324  case ISA_Motorola_M68HC12: return "Motorola_M68HC12";
325  case ISA_Fujitsu_MMA_Multimedia_Accelerator: return "Fujitsu_MMA_Multimedia_Accelerator";
326  case ISA_Siemens_PCP: return "Siemens_PCP";
327  case ISA_Sony_nCPU_embeeded_RISC: return "Sony_nCPU_embeeded_RISC";
328  case ISA_Denso_NDR1_microprocessor: return "Denso_NDR1_microprocessor";
329  case ISA_Motorola_Start_Core_processor: return "Motorola_Start_Core_processor";
330  case ISA_Toyota_ME16_processor: return "Toyota_ME16_processor";
331  case ISA_STMicroelectronic_ST100_processor: return "STMicroelectronic_ST100_processor";
332  case ISA_Advanced_Logic_Corp_Tinyj_emb_family: return "Advanced_Logic_Corp_Tinyj_emb_family";
333  case ISA_AMD_x86_64_architecture: return "AMD_x86_64_architecture";
334  case ISA_Sony_DSP_Processor: return "Sony_DSP_Processor";
335  case ISA_Siemens_FX66_microcontroller: return "Siemens_FX66_microcontroller";
336  case ISA_STMicroelectronics_ST9_plus_8_16_microcontroller: return "STMicroelectronics_ST9_plus_8_16_microcontroller";
337  case ISA_STMicroelectronics_ST7_8bit_microcontroller: return "STMicroelectronics_ST7_8bit_microcontroller";
338  case ISA_Motorola_MC68HC16_microcontroller: return "Motorola_MC68HC16_microcontroller";
339  case ISA_Motorola_MC68HC11_microcontroller: return "Motorola_MC68HC11_microcontroller";
340  case ISA_Motorola_MC68HC08_microcontroller: return "Motorola_MC68HC08_microcontroller";
341  case ISA_Motorola_MC68HC05_microcontroller: return "Motorola_MC68HC05_microcontroller";
342  case ISA_Silicon_Graphics_SVx: return "Silicon_Graphics_SVx";
343  case ISA_STMicroelectronics_ST19_8bit_microcontroller: return "STMicroelectronics_ST19_8bit_microcontroller";
344  case ISA_Digital_VAX: return "Digital_VAX";
345  case ISA_Axis_Communications_32bit_embedded_processor: return "Axis_Communications_32bit_embedded_processor";
346  case ISA_Infineon_Technologies_32bit_embedded_processor: return "Infineon_Technologies_32bit_embedded_processor";
347  case ISA_Element_14_64bit_DSP_Processor: return "Element_14_64bit_DSP_Processor";
348  case ISA_LSI_Logic_16bit_DSP_Processor: return "LSI_Logic_16bit_DSP_Processor";
349  case ISA_Donald_Knuths_educational_64bit_processor: return "Donald_Knuths_educational_64bit_processor";
350  case ISA_Harvard_University_machine_independent_object_files: return "Harvard_University_machine_independent_object_files";
351  case ISA_SiTera_Prism: return "SiTera_Prism";
352  case ISA_Atmel_AVR_8bit_microcontroller: return "Atmel_AVR_8bit_microcontroller";
353  case ISA_Fujitsu_FR30: return "Fujitsu_FR30";
354  case ISA_Mitsubishi_D10V: return "Mitsubishi_D10V";
355  case ISA_Mitsubishi_D30V: return "Mitsubishi_D30V";
356  case ISA_NEC_v850: return "NEC_v850";
357  case ISA_Mitsubishi_M32R: return "Mitsubishi_M32R";
358  case ISA_Matsushita_MN10300: return "Matsushita_MN10300";
359  case ISA_Matsushita_MN10200: return "Matsushita_MN10200";
360  case ISA_picoJava: return "picoJava";
361  case ISA_OpenRISC_32bit_embedded_processor: return "OpenRISC_32bit_embedded_processor";
362  case ISA_ARC_Cores_Tangent_A5: return "ARC_Cores_Tangent_A5";
363  case ISA_Tensilica_Xtensa_Architecture: return "Tensilica_Xtensa_Architecture";
364  case ISA_Digital_Alpha: return "Digital_Alpha";
365  case ISA_Matsushita_AM33: return "Matsushita_AM33";
366  case ISA_EFI_ByteCode: return "EFI_ByteCode";
367 
368  case ISA_IA32_Family:
369  case ISA_X8664_Family:
370  case ISA_SPARC_Family:
371  case ISA_M68K_Family:
372  case ISA_M88K_Family:
373  case ISA_MIPS_Family:
374  case ISA_I860_Family:
375  case ISA_IA64_Family:
376  case ISA_ARM_Family:
377  case ISA_OTHER_Family:
378  return isa_family_to_string(isa);
379  };
380  char buf[64];
381  snprintf(buf,sizeof(buf),"unknown isa (%zu)",size_t(isa)) ;
382  return buf;
383 }
384 
386 {
387  switch(family){
388  case FAMILY_UNSPECIFIED: return "unspecified";
389  case FAMILY_DOS: return "Microsoft DOS";
390  case FAMILY_ELF: return "Executable and Linking Format (ELF)";
391  case FAMILY_LE: return "Microsoft Linear Executable (LE)";
392  case FAMILY_LX: return "OS/2 Extended Linear Executable (LX)";
393  case FAMILY_NE: return "Microsoft New Executable (NE)";
394  case FAMILY_PE: return "Microsoft Portable Executable (PE)";
395  };
396  char buf[128];
397  snprintf(buf,sizeof(buf),"unknown exec family (%zu)",size_t(family)) ;
398  return buf;
399 }
400 
402 {
403  switch(abi){
404  case ABI_UNSPECIFIED: return "unspecified";
405  case ABI_OTHER: return "other";
406  case ABI_86OPEN: return "86Open Common IA32";
407  case ABI_AIX: return "AIX";
408  case ABI_ARM: return "ARM architecture";
409  case ABI_FREEBSD: return "FreeBSD";
410  case ABI_HPUX: return "HP/UX";
411  case ABI_IRIX: return "IRIX";
412  case ABI_HURD: return "GNU/Hurd";
413  case ABI_LINUX: return "GNU/Linux";
414  case ABI_MODESTO: return "Novell Modesto";
415  case ABI_MONTEREY: return "Monterey project";
416  case ABI_MSDOS: return "Microsoft DOS";
417  case ABI_NT: return "Windows NT";
418  case ABI_NETBSD: return "NetBSD";
419  case ABI_OS2: return "OS/2";
420  case ABI_SOLARIS: return "Sun Solaris";
421  case ABI_SYSV: return "SysV R4";
422  case ABI_TRU64: return "Compaq TRU64 UNIX";
423  case ABI_WIN386: return "Microsoft Windows";
424  };
425  char buf[64];
426  snprintf(buf,sizeof(buf),"unknown abi (%zu)",size_t(abi)) ;
427  return buf;
428 }
429 
431 {
432  switch(purpose){
433  case PURPOSE_UNSPECIFIED: return "unspecified";
434  case PURPOSE_OTHER: return "other";
435  case PURPOSE_EXECUTABLE: return "executable program";
436  case PURPOSE_LIBRARY: return "library (shared or relocatable)";
437  case PURPOSE_CORE_DUMP: return "post mortem image (core dump)";
438  case PURPOSE_OS_SPECIFIC: return "operating system specific purpose";
439  case PURPOSE_PROC_SPECIFIC: return "processor specific purpose";
440  };
441  char buf[64];
442  snprintf(buf,sizeof(buf),"unknown exec purpose (%zu)",size_t(purpose)) ;
443  return buf;
444 }