1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843 |
- /* od-xcoff.c -- dump information about an xcoff object file.
- Copyright (C) 2011-2015 Free Software Foundation, Inc.
- Written by Tristan Gingold, Adacore.
- This file is part of GNU Binutils.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 51 Franklin Street - Fifth Floor, Boston,
- MA 02110-1301, USA. */
- #include "sysdep.h"
- #include <stddef.h>
- #include <time.h>
- #include "safe-ctype.h"
- #include "bfd.h"
- #include "objdump.h"
- #include "bucomm.h"
- #include "bfdlink.h"
- /* Force the support of weak symbols. */
- #ifndef AIX_WEAK_SUPPORT
- #define AIX_WEAK_SUPPORT 1
- #endif
- #include "coff/internal.h"
- #include "coff/rs6000.h"
- #include "coff/xcoff.h"
- #include "libcoff.h"
- #include "libxcoff.h"
- /* Index of the options in the options[] array. */
- #define OPT_FILE_HEADER 0
- #define OPT_AOUT 1
- #define OPT_SECTIONS 2
- #define OPT_SYMS 3
- #define OPT_RELOCS 4
- #define OPT_LINENO 5
- #define OPT_LOADER 6
- #define OPT_EXCEPT 7
- #define OPT_TYPCHK 8
- #define OPT_TRACEBACK 9
- #define OPT_TOC 10
- #define OPT_LDINFO 11
- /* List of actions. */
- static struct objdump_private_option options[] =
- {
- { "header", 0 },
- { "aout", 0 },
- { "sections", 0 },
- { "syms", 0 },
- { "relocs", 0 },
- { "lineno", 0 },
- { "loader", 0 },
- { "except", 0 },
- { "typchk", 0 },
- { "traceback", 0 },
- { "toc", 0 },
- { "ldinfo", 0 },
- { NULL, 0 }
- };
- /* Display help. */
- static void
- xcoff_help (FILE *stream)
- {
- fprintf (stream, _("\
- For XCOFF files:\n\
- header Display the file header\n\
- aout Display the auxiliary header\n\
- sections Display the section headers\n\
- syms Display the symbols table\n\
- relocs Display the relocation entries\n\
- lineno Display the line number entries\n\
- loader Display loader section\n\
- except Display exception table\n\
- typchk Display type-check section\n\
- traceback Display traceback tags\n\
- toc Display toc symbols\n\
- ldinfo Display loader info in core files\n\
- "));
- }
- /* Return TRUE if ABFD is handled. */
- static int
- xcoff_filter (bfd *abfd)
- {
- return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
- }
- /* Translation entry type. The last entry must be {0, NULL}. */
- struct xlat_table {
- unsigned int val;
- const char *name;
- };
- /* Display the list of name (from TABLE) for FLAGS, using comma to separate
- them. A name is displayed if FLAGS & VAL is not 0. */
- static void
- dump_flags (const struct xlat_table *table, unsigned int flags)
- {
- unsigned int r = flags;
- int first = 1;
- const struct xlat_table *t;
- for (t = table; t->name; t++)
- if ((flags & t->val) != 0)
- {
- r &= ~t->val;
- if (first)
- first = 0;
- else
- putchar (',');
- fputs (t->name, stdout);
- }
- /* Not decoded flags. */
- if (r != 0)
- {
- if (!first)
- putchar (',');
- printf ("0x%x", r);
- }
- }
- /* Display the name corresponding to VAL from TABLE, using at most
- MAXLEN char (possibly passed with spaces). */
- static void
- dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
- {
- const struct xlat_table *t;
- for (t = table; t->name; t++)
- if (t->val == val)
- {
- printf ("%-*s", maxlen, t->name);
- return;
- }
- printf ("(%*x)", maxlen - 2, val);
- }
- /* Names of f_flags. */
- static const struct xlat_table f_flag_xlat[] =
- {
- { F_RELFLG, "no-rel" },
- { F_EXEC, "exec" },
- { F_LNNO, "lineno" },
- { F_LSYMS, "lsyms" },
- { F_FDPR_PROF, "fdpr-prof" },
- { F_FDPR_OPTI, "fdpr-opti" },
- { F_DSA, "dsa" },
- { F_VARPG, "varprg" },
- { F_DYNLOAD, "dynload" },
- { F_SHROBJ, "shrobj" },
- { F_NONEXEC, "nonexec" },
- { 0, NULL }
- };
- /* Names of s_flags. */
- static const struct xlat_table s_flag_xlat[] =
- {
- { STYP_PAD, "pad" },
- { STYP_DWARF, "dwarf" },
- { STYP_TEXT, "text" },
- { STYP_DATA, "data" },
- { STYP_BSS, "bss" },
- { STYP_EXCEPT, "except" },
- { STYP_INFO, "info" },
- { STYP_TDATA, "tdata" },
- { STYP_TBSS, "tbss" },
- { STYP_LOADER, "loader" },
- { STYP_DEBUG, "debug" },
- { STYP_TYPCHK, "typchk" },
- { STYP_OVRFLO, "ovrflo" },
- { 0, NULL }
- };
- /* Names of storage class. */
- static const struct xlat_table sc_xlat[] =
- {
- #define SC_ENTRY(X) { C_##X, #X }
- SC_ENTRY(NULL),
- SC_ENTRY(AUTO),
- SC_ENTRY(EXT),
- SC_ENTRY(STAT),
- SC_ENTRY(REG),
- SC_ENTRY(EXTDEF),
- SC_ENTRY(LABEL),
- SC_ENTRY(ULABEL),
- SC_ENTRY(MOS),
- SC_ENTRY(ARG),
- /* SC_ENTRY(STRARG), */
- SC_ENTRY(MOU),
- SC_ENTRY(UNTAG),
- SC_ENTRY(TPDEF),
- SC_ENTRY(USTATIC),
- SC_ENTRY(ENTAG),
- SC_ENTRY(MOE),
- SC_ENTRY(REGPARM),
- SC_ENTRY(FIELD),
- SC_ENTRY(BLOCK),
- SC_ENTRY(FCN),
- SC_ENTRY(EOS),
- SC_ENTRY(FILE),
- SC_ENTRY(LINE),
- SC_ENTRY(ALIAS),
- SC_ENTRY(HIDDEN),
- SC_ENTRY(HIDEXT),
- SC_ENTRY(BINCL),
- SC_ENTRY(EINCL),
- SC_ENTRY(INFO),
- SC_ENTRY(WEAKEXT),
- SC_ENTRY(DWARF),
- /* Stabs. */
- SC_ENTRY (GSYM),
- SC_ENTRY (LSYM),
- SC_ENTRY (PSYM),
- SC_ENTRY (RSYM),
- SC_ENTRY (RPSYM),
- SC_ENTRY (STSYM),
- SC_ENTRY (TCSYM),
- SC_ENTRY (BCOMM),
- SC_ENTRY (ECOML),
- SC_ENTRY (ECOMM),
- SC_ENTRY (DECL),
- SC_ENTRY (ENTRY),
- SC_ENTRY (FUN),
- SC_ENTRY (BSTAT),
- SC_ENTRY (ESTAT),
- { 0, NULL }
- #undef SC_ENTRY
- };
- /* Names for symbol type. */
- static const struct xlat_table smtyp_xlat[] =
- {
- { XTY_ER, "ER" },
- { XTY_SD, "SD" },
- { XTY_LD, "LD" },
- { XTY_CM, "CM" },
- { XTY_EM, "EM" },
- { XTY_US, "US" },
- { 0, NULL }
- };
- /* Names for storage-mapping class. */
- static const struct xlat_table smclas_xlat[] =
- {
- #define SMCLAS_ENTRY(X) { XMC_##X, #X }
- SMCLAS_ENTRY (PR),
- SMCLAS_ENTRY (RO),
- SMCLAS_ENTRY (DB),
- SMCLAS_ENTRY (TC),
- SMCLAS_ENTRY (UA),
- SMCLAS_ENTRY (RW),
- SMCLAS_ENTRY (GL),
- SMCLAS_ENTRY (XO),
- SMCLAS_ENTRY (SV),
- SMCLAS_ENTRY (BS),
- SMCLAS_ENTRY (DS),
- SMCLAS_ENTRY (UC),
- SMCLAS_ENTRY (TI),
- SMCLAS_ENTRY (TB),
- SMCLAS_ENTRY (TC0),
- SMCLAS_ENTRY (TD),
- SMCLAS_ENTRY (SV64),
- SMCLAS_ENTRY (SV3264),
- { 0, NULL }
- #undef SMCLAS_ENTRY
- };
- /* Names for relocation type. */
- static const struct xlat_table rtype_xlat[] =
- {
- #define RTYPE_ENTRY(X) { R_##X, #X }
- RTYPE_ENTRY (POS),
- RTYPE_ENTRY (NEG),
- RTYPE_ENTRY (REL),
- RTYPE_ENTRY (TOC),
- RTYPE_ENTRY (RTB),
- RTYPE_ENTRY (GL),
- RTYPE_ENTRY (TCL),
- RTYPE_ENTRY (BA),
- RTYPE_ENTRY (BR),
- RTYPE_ENTRY (RL),
- RTYPE_ENTRY (RLA),
- RTYPE_ENTRY (REF),
- RTYPE_ENTRY (TRL),
- RTYPE_ENTRY (TRLA),
- RTYPE_ENTRY (RRTBI),
- RTYPE_ENTRY (RRTBA),
- RTYPE_ENTRY (CAI),
- RTYPE_ENTRY (CREL),
- RTYPE_ENTRY (RBA),
- RTYPE_ENTRY (RBAC),
- RTYPE_ENTRY (RBR),
- RTYPE_ENTRY (RBRC),
- RTYPE_ENTRY (TLS),
- RTYPE_ENTRY (TLS_IE),
- RTYPE_ENTRY (TLS_LD),
- RTYPE_ENTRY (TLS_LE),
- RTYPE_ENTRY (TLSM),
- RTYPE_ENTRY (TLSML),
- RTYPE_ENTRY (TOCU),
- RTYPE_ENTRY (TOCL),
- { 0, NULL }
- };
- /* Simplified section header. */
- struct xcoff32_section
- {
- /* NUL terminated name. */
- char name[9];
- /* Section flags. */
- unsigned int flags;
- /* Offsets in file. */
- ufile_ptr scnptr;
- ufile_ptr relptr;
- ufile_ptr lnnoptr;
- /* Number of relocs and line numbers. */
- unsigned int nreloc;
- unsigned int nlnno;
- };
- /* Simplified symbol. */
- union xcoff32_symbol
- {
- union external_auxent aux;
- struct sym
- {
- /* Pointer to the NUL-terminated name. */
- char *name;
- /* XCOFF symbol fields. */
- unsigned int val;
- unsigned short scnum;
- unsigned short ntype;
- unsigned char sclass;
- unsigned char numaux;
- /* Buffer in case the name is local. */
- union
- {
- char name[9];
- unsigned int off;
- } raw;
- } sym;
- };
- /* Important fields to dump the file. */
- struct xcoff_dump
- {
- /* From file header. */
- unsigned short nscns;
- unsigned int symptr;
- unsigned int nsyms;
- unsigned short opthdr;
- /* Sections. */
- struct xcoff32_section *sects;
- /* Symbols. */
- union xcoff32_symbol *syms;
- char *strings;
- unsigned int strings_size;
- };
- /* Print a symbol (if possible). */
- static void
- xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
- {
- if (data->syms != NULL
- && symndx < data->nsyms
- && data->syms[symndx].sym.name != NULL)
- printf ("%s", data->syms[symndx].sym.name);
- else
- printf ("%u", symndx);
- }
- /* Dump the file header. */
- static void
- dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
- struct xcoff_dump *data)
- {
- unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
- unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
- printf (_(" nbr sections: %d\n"), data->nscns);
- printf (_(" time and date: 0x%08x - "), timdat);
- if (timdat == 0)
- printf (_("not set\n"));
- else
- {
- /* Not correct on all platforms, but works on unix. */
- time_t t = timdat;
- fputs (ctime (&t), stdout);
- }
- printf (_(" symbols off: 0x%08x\n"), data->symptr);
- printf (_(" nbr symbols: %d\n"), data->nsyms);
- printf (_(" opt hdr sz: %d\n"), data->opthdr);
- printf (_(" flags: 0x%04x "), flags);
- dump_flags (f_flag_xlat, flags);
- putchar ('\n');
- }
- /* Dump the a.out header. */
- static void
- dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
- {
- AOUTHDR auxhdr;
- unsigned short magic;
- unsigned int sz = data->opthdr;
- printf (_("Auxiliary header:\n"));
- if (data->opthdr == 0)
- {
- printf (_(" No aux header\n"));
- return;
- }
- if (data->opthdr > sizeof (auxhdr))
- {
- printf (_("warning: optional header size too large (> %d)\n"),
- (int)sizeof (auxhdr));
- sz = sizeof (auxhdr);
- }
- if (bfd_bread (&auxhdr, sz, abfd) != sz)
- {
- non_fatal (_("cannot read auxhdr"));
- return;
- }
- magic = bfd_h_get_16 (abfd, auxhdr.magic);
- /* We don't translate these strings as they are fields name. */
- printf (" o_mflag (magic): 0x%04x 0%04o\n", magic, magic);
- printf (" o_vstamp: 0x%04x\n",
- (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
- printf (" o_tsize: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
- printf (" o_dsize: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
- printf (" o_entry: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
- printf (" o_text_start: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
- printf (" o_data_start: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
- if (sz == offsetof (AOUTHDR, o_toc))
- return;
- printf (" o_toc: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
- printf (" o_snentry: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
- printf (" o_sntext: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
- printf (" o_sndata: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
- printf (" o_sntoc: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
- printf (" o_snloader: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
- printf (" o_snbss: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
- printf (" o_algntext: %u\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
- printf (" o_algndata: %u\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
- printf (" o_modtype: 0x%04x",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
- if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
- printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
- putchar ('\n');
- printf (" o_cputype: 0x%04x\n",
- (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
- printf (" o_maxstack: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
- printf (" o_maxdata: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
- #if 0
- printf (" o_debugger: 0x%08x\n",
- (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
- #endif
- }
- /* Dump the sections header. */
- static void
- dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- unsigned int off;
- off = sizeof (struct external_filehdr) + data->opthdr;
- printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
- (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
- off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
- if (data->nscns == 0)
- {
- printf (_(" No section header\n"));
- return;
- }
- if (bfd_seek (abfd, off, SEEK_SET) != 0)
- {
- non_fatal (_("cannot read section header"));
- return;
- }
- /* We don't translate this string as it consists in fields name. */
- printf (" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n");
- for (i = 0; i < data->nscns; i++)
- {
- struct external_scnhdr scn;
- unsigned int flags;
- if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
- {
- non_fatal (_("cannot read section header"));
- return;
- }
- flags = bfd_h_get_32 (abfd, scn.s_flags);
- printf ("%2d %-8.8s %08x %08x %08x %08x %08x %08x %-5d %-5d\n",
- i + 1, scn.s_name,
- (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
- (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
- (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
- printf (_(" Flags: %08x "), flags);
- if (~flags == 0)
- {
- /* Stripped executable ? */
- putchar ('\n');
- }
- else if (flags & STYP_OVRFLO)
- printf (_("overflow - nreloc: %u, nlnno: %u\n"),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
- (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
- else
- {
- dump_flags (s_flag_xlat, flags);
- putchar ('\n');
- }
- }
- }
- /* Read section table. */
- static void
- xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
- {
- int i;
- if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
- SEEK_SET) != 0)
- {
- non_fatal (_("cannot read section headers"));
- return;
- }
- data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
- for (i = 0; i < data->nscns; i++)
- {
- struct external_scnhdr scn;
- struct xcoff32_section *s = &data->sects[i];
- if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
- {
- non_fatal (_("cannot read section header"));
- free (data->sects);
- data->sects = NULL;
- return;
- }
- memcpy (s->name, scn.s_name, 8);
- s->name[8] = 0;
- s->flags = bfd_h_get_32 (abfd, scn.s_flags);
- s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
- s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
- s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
- s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
- s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
- if (s->flags == STYP_OVRFLO)
- {
- if (s->nreloc > 0 && s->nreloc <= data->nscns)
- data->sects[s->nreloc - 1].nreloc =
- bfd_h_get_32 (abfd, scn.s_paddr);
- if (s->nlnno > 0 && s->nlnno <= data->nscns)
- data->sects[s->nlnno - 1].nlnno =
- bfd_h_get_32 (abfd, scn.s_vaddr);
- }
- }
- }
- /* Read symbols. */
- static void
- xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- char stsz_arr[4];
- unsigned int stptr;
- if (data->nsyms == 0)
- return;
- stptr = data->symptr
- + data->nsyms * (unsigned)sizeof (struct external_syment);
- /* Read string table. */
- if (bfd_seek (abfd, stptr, SEEK_SET) != 0
- || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
- {
- non_fatal (_("cannot read strings table length"));
- data->strings_size = 0;
- }
- else
- {
- data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
- if (data->strings_size > sizeof (stsz_arr))
- {
- unsigned int remsz = data->strings_size - sizeof (stsz_arr);
- data->strings = xmalloc (data->strings_size);
- memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
- if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
- != remsz)
- {
- non_fatal (_("cannot read strings table"));
- goto clean;
- }
- }
- }
- if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
- {
- non_fatal (_("cannot read symbol table"));
- goto clean;
- }
- data->syms = (union xcoff32_symbol *)
- xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
- for (i = 0; i < data->nsyms; i++)
- {
- struct external_syment sym;
- int j;
- union xcoff32_symbol *s = &data->syms[i];
- if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
- {
- non_fatal (_("cannot read symbol entry"));
- goto clean;
- }
- s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
- s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
- s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
- s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
- s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
- if (sym.e.e_name[0])
- {
- memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
- s->sym.raw.name[8] = 0;
- s->sym.name = s->sym.raw.name;
- }
- else
- {
- unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
- if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
- s->sym.name = data->strings + soff;
- else
- {
- s->sym.name = NULL;
- s->sym.raw.off = soff;
- }
- }
- for (j = 0; j < s->sym.numaux; j++, i++)
- {
- if (bfd_bread (&s[j + 1].aux,
- sizeof (union external_auxent), abfd)
- != sizeof (union external_auxent))
- {
- non_fatal (_("cannot read symbol aux entry"));
- goto clean;
- }
- }
- }
- return;
- clean:
- free (data->syms);
- data->syms = NULL;
- free (data->strings);
- data->strings = NULL;
- }
- /* Dump xcoff symbols. */
- static void
- dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- asection *debugsec;
- char *debug = NULL;
- printf (_("Symbols table (strtable at 0x%08x)"),
- data->symptr
- + data->nsyms * (unsigned)sizeof (struct external_syment));
- if (data->nsyms == 0 || data->syms == NULL)
- {
- printf (_(":\n No symbols\n"));
- return;
- }
- /* Read strings table. */
- if (data->strings_size == 0)
- printf (_(" (no strings):\n"));
- else
- printf (_(" (strings size: %08x):\n"), data->strings_size);
- /* Read debug section. */
- debugsec = bfd_get_section_by_name (abfd, ".debug");
- if (debugsec != NULL)
- {
- bfd_size_type size;
- size = bfd_get_section_size (debugsec);
- debug = (char *) xmalloc (size);
- bfd_get_section_contents (abfd, debugsec, debug, 0, size);
- }
- /* Translators: 'sc' is for storage class, 'off' for offset. */
- printf (_(" # sc value section type aux name/off\n"));
- for (i = 0; i < data->nsyms; i++)
- {
- union xcoff32_symbol *s = &data->syms[i];
- int j;
- printf ("%3u ", i);
- dump_value (sc_xlat, s->sym.sclass, 10);
- printf (" %08x ", s->sym.val);
- if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
- {
- if (data->sects != NULL)
- printf ("%-8s", data->sects[s->sym.scnum - 1].name);
- else
- printf ("%-8u", s->sym.scnum);
- }
- else
- switch ((signed short)s->sym.scnum)
- {
- case N_DEBUG:
- printf ("N_DEBUG ");
- break;
- case N_ABS:
- printf ("N_ABS ");
- break;
- case N_UNDEF:
- printf ("N_UNDEF ");
- break;
- default:
- printf ("(%04x) ", s->sym.scnum);
- }
- printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
- if (s->sym.name != NULL)
- printf ("%s", s->sym.name);
- else
- {
- if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
- printf ("%s", debug + s->sym.raw.off);
- else
- printf ("%08x", s->sym.raw.off);
- }
- putchar ('\n');
- for (j = 0; j < s->sym.numaux; j++, i++)
- {
- union external_auxent *aux = &s[j + 1].aux;
- printf (" %3u ", i + 1);
- switch (s->sym.sclass)
- {
- case C_STAT:
- /* Section length, number of relocs and line number. */
- printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-6u\n"),
- (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
- (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
- (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
- break;
- case C_DWARF:
- /* Section length and number of relocs. */
- printf (_(" scnlen: %08x nreloc: %-6u\n"),
- (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
- (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
- break;
- case C_EXT:
- case C_WEAKEXT:
- case C_HIDEXT:
- if (j == 0 && s->sym.numaux > 1)
- {
- /* Function aux entry (Do not translate). */
- printf (" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n",
- (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
- (unsigned)bfd_h_get_32
- (abfd, aux->x_sym.x_misc.x_fsize),
- (unsigned)bfd_h_get_32
- (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
- (unsigned)bfd_h_get_32
- (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
- }
- else if (j == 1 || (j == 0 && s->sym.numaux == 1))
- {
- /* csect aux entry. */
- unsigned char smtyp;
- unsigned int scnlen;
- smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
- scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
- if (smtyp == XTY_LD)
- printf (" scnsym: %-8u", scnlen);
- else
- printf (" scnlen: %08x", scnlen);
- printf (" h: parm=%08x sn=%04x al: 2**%u",
- (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
- (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
- SMTYP_ALIGN (smtyp));
- printf (" typ: ");
- dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
- printf (" cl: ");
- dump_value
- (smclas_xlat,
- (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
- putchar ('\n');
- }
- else
- /* Do not translate - generic field name. */
- printf ("aux\n");
- break;
- case C_FILE:
- {
- unsigned int off;
- printf (" ftype: %02x ",
- (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
- if (aux->x_file.x_n.x_fname[0] != 0)
- printf ("fname: %.14s", aux->x_file.x_n.x_fname);
- else
- {
- off = (unsigned)bfd_h_get_32
- (abfd, aux->x_file.x_n.x_n.x_offset);
- if (data->strings != NULL && off < data->strings_size)
- printf (" %s", data->strings + off);
- else
- printf (_("offset: %08x"), off);
- }
- putchar ('\n');
- }
- break;
- case C_BLOCK:
- case C_FCN:
- printf (" lnno: %u\n",
- (unsigned)bfd_h_get_16
- (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
- break;
- default:
- /* Do not translate - generic field name. */
- printf ("aux\n");
- break;
- }
- }
- }
- free (debug);
- }
- /* Dump xcoff relocation entries. */
- static void
- dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- if (data->sects == NULL)
- {
- non_fatal (_("cannot read section headers"));
- return;
- }
- for (i = 0; i < data->nscns; i++)
- {
- struct xcoff32_section *sect = &data->sects[i];
- unsigned int nrel = sect->nreloc;
- unsigned int j;
- if (nrel == 0)
- continue;
- printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
- if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
- {
- non_fatal (_("cannot read relocations"));
- continue;
- }
- /* Do not translate: fields name. */
- printf ("vaddr sgn mod sz type symndx symbol\n");
- for (j = 0; j < nrel; j++)
- {
- struct external_reloc rel;
- unsigned char rsize;
- unsigned int symndx;
- if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
- {
- non_fatal (_("cannot read relocation entry"));
- return;
- }
- rsize = bfd_h_get_8 (abfd, rel.r_size);
- printf ("%08x %c %c %-2u ",
- (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
- rsize & 0x80 ? 'S' : 'U',
- rsize & 0x40 ? 'm' : ' ',
- (rsize & 0x3f) + 1);
- dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
- symndx = bfd_h_get_32 (abfd, rel.r_symndx);
- printf ("%-6u ", symndx);
- xcoff32_print_symbol (data, symndx);
- putchar ('\n');
- }
- putchar ('\n');
- }
- }
- /* Dump xcoff line number entries. */
- static void
- dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- if (data->sects == NULL)
- {
- non_fatal (_("cannot read section headers"));
- return;
- }
- for (i = 0; i < data->nscns; i++)
- {
- struct xcoff32_section *sect = &data->sects[i];
- unsigned int nlnno = sect->nlnno;
- unsigned int j;
- if (nlnno == 0)
- continue;
- printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
- if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
- {
- non_fatal (_("cannot read line numbers"));
- continue;
- }
- /* Line number, symbol index and physical address. */
- printf (_("lineno symndx/paddr\n"));
- for (j = 0; j < nlnno; j++)
- {
- struct external_lineno ln;
- unsigned int no;
- if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
- {
- non_fatal (_("cannot read line number entry"));
- return;
- }
- no = bfd_h_get_16 (abfd, ln.l_lnno);
- printf (" %-6u ", no);
- if (no == 0)
- {
- unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
- xcoff32_print_symbol (data, symndx);
- }
- else
- printf ("0x%08x",
- (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
- putchar ('\n');
- }
- }
- }
- /* Dump xcoff loader section. */
- static void
- dump_xcoff32_loader (bfd *abfd)
- {
- asection *loader;
- bfd_size_type size = 0;
- struct external_ldhdr *lhdr;
- struct external_ldsym *ldsym;
- struct external_ldrel *ldrel;
- bfd_byte *ldr_data;
- unsigned int version;
- unsigned int ndsyms;
- unsigned int ndrel;
- unsigned int stlen;
- unsigned int stoff;
- unsigned int impoff;
- unsigned int nimpid;
- unsigned int i;
- const char *p;
- loader = bfd_get_section_by_name (abfd, ".loader");
- if (loader == NULL)
- {
- printf (_("no .loader section in file\n"));
- return;
- }
- size = bfd_get_section_size (loader);
- if (size < sizeof (*lhdr))
- {
- printf (_("section .loader is too short\n"));
- return;
- }
- ldr_data = (bfd_byte *) xmalloc (size);
- bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
- lhdr = (struct external_ldhdr *)ldr_data;
- printf (_("Loader header:\n"));
- version = bfd_h_get_32 (abfd, lhdr->l_version);
- printf (_(" version: %u\n"), version);
- if (version != 1)
- {
- printf (_(" Unhandled version\n"));
- free (ldr_data);
- return;
- }
- ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
- printf (_(" nbr symbols: %u\n"), ndsyms);
- ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
- printf (_(" nbr relocs: %u\n"), ndrel);
- /* Import string table length. */
- printf (_(" import strtab len: %u\n"),
- (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
- nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
- printf (_(" nbr import files: %u\n"), nimpid);
- impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
- printf (_(" import file off: %u\n"), impoff);
- stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
- printf (_(" string table len: %u\n"), stlen);
- stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
- printf (_(" string table off: %u\n"), stoff);
- ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
- printf (_("Dynamic symbols:\n"));
- /* Do not translate: field names. */
- printf (" # value sc IFEW ty class file pa name\n");
- for (i = 0; i < ndsyms; i++, ldsym++)
- {
- unsigned char smtype;
- printf (_(" %4u %08x %3u "), i,
- (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
- (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
- smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
- putchar (smtype & 0x40 ? 'I' : ' ');
- putchar (smtype & 0x20 ? 'F' : ' ');
- putchar (smtype & 0x10 ? 'E' : ' ');
- putchar (smtype & 0x08 ? 'W' : ' ');
- putchar (' ');
- dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
- putchar (' ');
- dump_value
- (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
- printf (_(" %3u %3u "),
- (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
- (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
- if (ldsym->_l._l_name[0] != 0)
- printf ("%-.8s", ldsym->_l._l_name);
- else
- {
- unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
- if (off > stlen)
- printf (_("(bad offset: %u)"), off);
- else
- printf ("%s", ldr_data + stoff + off);
- }
- putchar ('\n');
- }
- printf (_("Dynamic relocs:\n"));
- /* Do not translate fields name. */
- printf (" vaddr sec sz typ sym\n");
- ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
- + ndsyms * sizeof (*ldsym));
- for (i = 0; i < ndrel; i++, ldrel++)
- {
- unsigned int rsize;
- unsigned int rtype;
- unsigned int symndx;
- rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
- rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
- printf (" %08x %3u %c%c %2u ",
- (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
- (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
- rsize & 0x80 ? 'S' : 'U',
- rsize & 0x40 ? 'm' : ' ',
- (rsize & 0x3f) + 1);
- dump_value (rtype_xlat, rtype, 6);
- symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
- switch (symndx)
- {
- case 0:
- printf (".text");
- break;
- case 1:
- printf (".data");
- break;
- case 2:
- printf (".bss");
- break;
- default:
- printf ("%u", symndx - 3);
- break;
- }
- putchar ('\n');
- }
- printf (_("Import files:\n"));
- p = (char *)ldr_data + impoff;
- for (i = 0; i < nimpid; i++)
- {
- int n1, n2, n3;
- n1 = strlen (p);
- n2 = strlen (p + n1 + 1);
- n3 = strlen (p + n1 + 1 + n2+ 1);
- printf (" %2u: %s,%s,%s\n", i,
- p, p + n1 + 1, p + n1 + n2 + 2);
- p += n1 + n2 + n3 + 3;
- }
- free (ldr_data);
- }
- /* Dump xcoff exception section. */
- static void
- dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
- {
- asection *sec;
- bfd_size_type size = 0;
- bfd_byte *excp_data;
- struct external_exceptab *exceptab;
- unsigned int i;
- sec = bfd_get_section_by_name (abfd, ".except");
- if (sec == NULL)
- {
- printf (_("no .except section in file\n"));
- return;
- }
- size = bfd_get_section_size (sec);
- excp_data = (bfd_byte *) xmalloc (size);
- bfd_get_section_contents (abfd, sec, excp_data, 0, size);
- exceptab = (struct external_exceptab *)excp_data;
- printf (_("Exception table:\n"));
- /* Do not translate fields name. */
- printf ("lang reason sym/addr\n");
- for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
- {
- unsigned int reason;
- unsigned int addr;
- addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
- reason = bfd_get_8 (abfd, exceptab->e_reason);
- printf (" %02x %02x ",
- (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
- if (reason == 0)
- xcoff32_print_symbol (data, addr);
- else
- printf ("@%08x", addr);
- putchar ('\n');
- }
- free (excp_data);
- }
- /* Dump xcoff type-check section. */
- static void
- dump_xcoff32_typchk (bfd *abfd)
- {
- asection *sec;
- bfd_size_type size = 0;
- bfd_byte *data;
- unsigned int i;
- sec = bfd_get_section_by_name (abfd, ".typchk");
- if (sec == NULL)
- {
- printf (_("no .typchk section in file\n"));
- return;
- }
- size = bfd_get_section_size (sec);
- data = (bfd_byte *) xmalloc (size);
- bfd_get_section_contents (abfd, sec, data, 0, size);
- printf (_("Type-check section:\n"));
- /* Do not translate field names. */
- printf ("offset len lang-id general-hash language-hash\n");
- for (i = 0; i < size;)
- {
- unsigned int len;
- len = bfd_get_16 (abfd, data + i);
- printf ("%08x: %-4u ", i, len);
- i += 2;
- if (len == 10)
- {
- /* Expected format. */
- printf ("%04x %08x %08x\n",
- (unsigned) bfd_get_16 (abfd, data + i),
- (unsigned) bfd_get_32 (abfd, data + i + 2),
- (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
- }
- else
- {
- unsigned int j;
- for (j = 0; j < len; j++)
- {
- if (j % 16 == 0)
- printf ("\n ");
- printf (" %02x", (unsigned char)data[i + j]);
- }
- putchar ('\n');
- }
- i += len;
- }
- free (data);
- }
- /* Dump xcoff traceback tags section. */
- static void
- dump_xcoff32_tbtags (bfd *abfd,
- const char *text, bfd_size_type text_size,
- unsigned int text_start, unsigned int func_start)
- {
- unsigned int i;
- if (func_start - text_start > text_size)
- {
- printf (_(" address beyond section size\n"));
- return;
- }
- for (i = func_start - text_start; i < text_size; i+= 4)
- if (bfd_get_32 (abfd, text + i) == 0)
- {
- unsigned int tb1;
- unsigned int tb2;
- unsigned int off;
- printf (_(" tags at %08x\n"), i + 4);
- if (i + 8 >= text_size)
- goto truncated;
- tb1 = bfd_get_32 (abfd, text + i + 4);
- tb2 = bfd_get_32 (abfd, text + i + 8);
- off = i + 12;
- printf (" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n",
- (tb1 >> 24) & 0xff,
- (tb1 >> 16) & 0xff,
- (tb1 >> 15) & 1,
- (tb1 >> 14) & 1,
- (tb1 >> 13) & 1,
- (tb1 >> 12) & 1);
- printf (" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n",
- (tb1 >> 11) & 1,
- (tb1 >> 10) & 1,
- (tb1 >> 9) & 1,
- (tb1 >> 8) & 1,
- (tb1 >> 7) & 1);
- printf (" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n",
- (tb1 >> 6) & 1,
- (tb1 >> 5) & 1,
- (tb1 >> 2) & 7,
- (tb1 >> 1) & 1,
- (tb1 >> 0) & 1);
- printf (" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n",
- (tb2 >> 31) & 1,
- (tb2 >> 30) & 1,
- (tb2 >> 24) & 63,
- (tb2 >> 22) & 3,
- (tb2 >> 16) & 63);
- printf (" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n",
- (tb2 >> 8) & 0xff,
- (tb2 >> 1) & 0x7f,
- (tb2 >> 0) & 1);
- if (((tb2 >> 1) & 0x7fff) != 0)
- {
- unsigned int parminfo;
- if (off >= text_size)
- goto truncated;
- parminfo = bfd_get_32 (abfd, text + off);
- off += 4;
- printf (" parminfo: 0x%08x\n", parminfo);
- }
- if ((tb1 >> 13) & 1)
- {
- unsigned int tboff;
- if (off >= text_size)
- goto truncated;
- tboff = bfd_get_32 (abfd, text + off);
- off += 4;
- printf (" tb_offset: 0x%08x (start=0x%08x)\n",
- tboff, text_start + i - tboff);
- }
- if ((tb1 >> 7) & 1)
- {
- unsigned int hand_mask;
- if (off >= text_size)
- goto truncated;
- hand_mask = bfd_get_32 (abfd, text + off);
- off += 4;
- printf (" hand_mask_offset: 0x%08x\n", hand_mask);
- }
- if ((tb1 >> 11) & 1)
- {
- unsigned int ctl_info;
- unsigned int j;
- if (off >= text_size)
- goto truncated;
- ctl_info = bfd_get_32 (abfd, text + off);
- off += 4;
- printf (_(" number of CTL anchors: %u\n"), ctl_info);
- for (j = 0; j < ctl_info; j++)
- {
- if (off >= text_size)
- goto truncated;
- printf (" CTL[%u]: %08x\n",
- j, (unsigned)bfd_get_32 (abfd, text + off));
- off += 4;
- }
- }
- if ((tb1 >> 6) & 1)
- {
- unsigned int name_len;
- unsigned int j;
- if (off >= text_size)
- goto truncated;
- name_len = bfd_get_16 (abfd, text + off);
- off += 2;
- printf (_(" Name (len: %u): "), name_len);
- if (off + name_len >= text_size)
- {
- printf (_("[truncated]\n"));
- goto truncated;
- }
- for (j = 0; j < name_len; j++)
- if (ISPRINT (text[off + j]))
- putchar (text[off + j]);
- else
- printf ("[%02x]", (unsigned char)text[off + j]);
- putchar ('\n');
- off += name_len;
- }
- if ((tb1 >> 5) & 1)
- {
- if (off >= text_size)
- goto truncated;
- printf (" alloca reg: %u\n",
- (unsigned) bfd_get_8 (abfd, text + off));
- off++;
- }
- printf (_(" (end of tags at %08x)\n"), text_start + off);
- return;
- }
- printf (_(" no tags found\n"));
- return;
- truncated:
- printf (_(" Truncated .text section\n"));
- return;
- }
- static void
- dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- unsigned int scnum_text = -1;
- unsigned int text_vma;
- asection *text_sec;
- bfd_size_type text_size;
- char *text;
- if (data->syms == NULL || data->sects == NULL)
- return;
- /* Read text section. */
- text_sec = bfd_get_section_by_name (abfd, ".text");
- if (text_sec == NULL)
- return;
- text_vma = bfd_get_section_vma (abfd, text_sec);
- text_size = bfd_get_section_size (text_sec);
- text = (char *) xmalloc (text_size);
- bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
- for (i = 0; i < data->nscns; i++)
- if (data->sects[i].flags == STYP_TEXT)
- {
- scnum_text = i + 1;
- break;
- }
- if (scnum_text == (unsigned int)-1)
- return;
- for (i = 0; i < data->nsyms; i++)
- {
- union xcoff32_symbol *s = &data->syms[i];
- switch (s->sym.sclass)
- {
- case C_EXT:
- case C_HIDEXT:
- case C_WEAKEXT:
- if (s->sym.scnum == scnum_text
- && s->sym.numaux > 0)
- {
- union external_auxent *aux = &s[s->sym.numaux].aux;
- unsigned int smtyp;
- unsigned int smclas;
- smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
- smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
- if (SMTYP_SMTYP (smtyp) == XTY_LD
- && (smclas == XMC_PR
- || smclas == XMC_GL
- || smclas == XMC_XO))
- {
- printf ("%08x: ", s->sym.val);
- xcoff32_print_symbol (data, i);
- putchar ('\n');
- dump_xcoff32_tbtags (abfd, text, text_size,
- text_vma, s->sym.val);
- }
- }
- break;
- default:
- break;
- }
- i += s->sym.numaux;
- }
- free (text);
- }
- /* Dump the TOC symbols. */
- static void
- dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
- {
- unsigned int i;
- unsigned int nbr_ent;
- unsigned int size;
- printf (_("TOC:\n"));
- if (data->syms == NULL)
- return;
- nbr_ent = 0;
- size = 0;
- for (i = 0; i < data->nsyms; i++)
- {
- union xcoff32_symbol *s = &data->syms[i];
- switch (s->sym.sclass)
- {
- case C_EXT:
- case C_HIDEXT:
- case C_WEAKEXT:
- if (s->sym.numaux > 0)
- {
- union external_auxent *aux = &s[s->sym.numaux].aux;
- unsigned int smclas;
- unsigned int ent_sz;
- smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
- if (smclas == XMC_TC
- || smclas == XMC_TD
- || smclas == XMC_TC0)
- {
- ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
- printf ("%08x %08x ",
- s->sym.val, ent_sz);
- xcoff32_print_symbol (data, i);
- putchar ('\n');
- nbr_ent++;
- size += ent_sz;
- }
- }
- break;
- default:
- break;
- }
- i += s->sym.numaux;
- }
- printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
- nbr_ent, size, size);
- }
- /* Handle an rs6000 xcoff file. */
- static void
- dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
- {
- struct xcoff_dump data;
- data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
- data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
- data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
- data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
- data.sects = NULL;
- data.syms = NULL;
- data.strings = NULL;
- data.strings_size = 0;
- if (options[OPT_FILE_HEADER].selected)
- dump_xcoff32_file_header (abfd, fhdr, &data);
- if (options[OPT_AOUT].selected)
- dump_xcoff32_aout_header (abfd, &data);
- if (options[OPT_SYMS].selected
- || options[OPT_RELOCS].selected
- || options[OPT_LINENO].selected
- || options[OPT_TRACEBACK].selected)
- xcoff32_read_sections (abfd, &data);
- if (options[OPT_SECTIONS].selected)
- dump_xcoff32_sections_header (abfd, &data);
- if (options[OPT_SYMS].selected
- || options[OPT_RELOCS].selected
- || options[OPT_LINENO].selected
- || options[OPT_EXCEPT].selected
- || options[OPT_TRACEBACK].selected
- || options[OPT_TOC].selected)
- xcoff32_read_symbols (abfd, &data);
- if (options[OPT_SYMS].selected)
- dump_xcoff32_symbols (abfd, &data);
- if (options[OPT_RELOCS].selected)
- dump_xcoff32_relocs (abfd, &data);
- if (options[OPT_LINENO].selected)
- dump_xcoff32_lineno (abfd, &data);
- if (options[OPT_LOADER].selected)
- dump_xcoff32_loader (abfd);
- if (options[OPT_EXCEPT].selected)
- dump_xcoff32_except (abfd, &data);
- if (options[OPT_TYPCHK].selected)
- dump_xcoff32_typchk (abfd);
- if (options[OPT_TRACEBACK].selected)
- dump_xcoff32_traceback (abfd, &data);
- if (options[OPT_TOC].selected)
- dump_xcoff32_toc (abfd, &data);
- free (data.sects);
- free (data.strings);
- free (data.syms);
- }
- /* Dump ABFD (according to the options[] array). */
- static void
- xcoff_dump_obj (bfd *abfd)
- {
- struct external_filehdr fhdr;
- unsigned short magic;
- /* Read file header. */
- if (bfd_seek (abfd, 0, SEEK_SET) != 0
- || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
- {
- non_fatal (_("cannot read header"));
- return;
- }
- /* Decoding. We don't use the bfd/coff function to get all the fields. */
- magic = bfd_h_get_16 (abfd, fhdr.f_magic);
- if (options[OPT_FILE_HEADER].selected)
- {
- printf (_("File header:\n"));
- printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
- switch (magic)
- {
- case U802WRMAGIC:
- printf (_("(WRMAGIC: writable text segments)"));
- break;
- case U802ROMAGIC:
- printf (_("(ROMAGIC: readonly sharablee text segments)"));
- break;
- case U802TOCMAGIC:
- printf (_("(TOCMAGIC: readonly text segments and TOC)"));
- break;
- default:
- printf (_("unknown magic"));
- break;
- }
- putchar ('\n');
- }
- if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
- dump_xcoff32 (abfd, &fhdr);
- else
- printf (_(" Unhandled magic\n"));
- }
- /* Handle an AIX dumpx core file. */
- static void
- dump_dumpx_core (bfd *abfd, struct external_core_dumpx *hdr)
- {
- if (options[OPT_FILE_HEADER].selected)
- {
- printf (" signal: %u\n", bfd_h_get_8 (abfd, hdr->c_signo));
- printf (" flags: 0x%02x\n", bfd_h_get_8 (abfd, hdr->c_flag));
- printf (" entries: %u\n",
- (unsigned) bfd_h_get_16 (abfd, hdr->c_entries));
- #ifdef BFD64
- printf (" fdsinfox: offset: 0x%08" BFD_VMA_FMT "x\n",
- bfd_h_get_64 (abfd, hdr->c_fdsinfox));
- printf (" loader: offset: 0x%08" BFD_VMA_FMT "x, "
- "size: 0x%" BFD_VMA_FMT"x\n",
- bfd_h_get_64 (abfd, hdr->c_loader),
- bfd_h_get_64 (abfd, hdr->c_lsize));
- printf (" thr: offset: 0x%08" BFD_VMA_FMT "x, nbr: %u\n",
- bfd_h_get_64 (abfd, hdr->c_thr),
- (unsigned) bfd_h_get_32 (abfd, hdr->c_n_thr));
- printf (" segregions: offset: 0x%08" BFD_VMA_FMT "x, "
- "nbr: %" BFD_VMA_FMT "u\n",
- bfd_h_get_64 (abfd, hdr->c_segregion),
- bfd_h_get_64 (abfd, hdr->c_segs));
- printf (" stack: offset: 0x%08" BFD_VMA_FMT "x, "
- "org: 0x%" BFD_VMA_FMT"x, "
- "size: 0x%" BFD_VMA_FMT"x\n",
- bfd_h_get_64 (abfd, hdr->c_stack),
- bfd_h_get_64 (abfd, hdr->c_stackorg),
- bfd_h_get_64 (abfd, hdr->c_size));
- printf (" data: offset: 0x%08" BFD_VMA_FMT "x, "
- "org: 0x%" BFD_VMA_FMT"x, "
- "size: 0x%" BFD_VMA_FMT"x\n",
- bfd_h_get_64 (abfd, hdr->c_data),
- bfd_h_get_64 (abfd, hdr->c_dataorg),
- bfd_h_get_64 (abfd, hdr->c_datasize));
- printf (" sdata: org: 0x%" BFD_VMA_FMT"x, "
- "size: 0x%" BFD_VMA_FMT"x\n",
- bfd_h_get_64 (abfd, hdr->c_sdorg),
- bfd_h_get_64 (abfd, hdr->c_sdsize));
- printf (" vmmregions: offset: 0x%" BFD_VMA_FMT"x, "
- "num: 0x%" BFD_VMA_FMT"x\n",
- bfd_h_get_64 (abfd, hdr->c_vmm),
- bfd_h_get_64 (abfd, hdr->c_vmmregions));
- printf (" impl: 0x%08x\n",
- (unsigned) bfd_h_get_32 (abfd, hdr->c_impl));
- printf (" cprs: 0x%" BFD_VMA_FMT "x\n",
- bfd_h_get_64 (abfd, hdr->c_cprs));
- #endif
- }
- if (options[OPT_LDINFO].selected)
- {
- #ifdef BFD64
- file_ptr off = (file_ptr) bfd_h_get_64 (abfd, hdr->c_loader);
- bfd_size_type len = (bfd_size_type) bfd_h_get_64 (abfd, hdr->c_lsize);
- char *ldr;
- ldr = xmalloc (len);
- if (bfd_seek (abfd, off, SEEK_SET) != 0
- || bfd_bread (ldr, len, abfd) != len)
- non_fatal (_("cannot read loader info table"));
- else
- {
- char *p;
- printf ("\n"
- "ld info:\n");
- printf (" next core off textorg textsize dataorg datasize\n");
- p = ldr;
- while (1)
- {
- struct external_ld_info32 *l = (struct external_ld_info32 *)p;
- unsigned int next;
- size_t n1;
- next = bfd_h_get_32 (abfd, l->ldinfo_next);
- printf (" %08x %08x %08x %08x %08x %08x\n",
- next,
- (unsigned) bfd_h_get_32 (abfd, l->core_offset),
- (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textorg),
- (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textsize),
- (unsigned) bfd_h_get_32 (abfd, l->ldinfo_dataorg),
- (unsigned) bfd_h_get_32 (abfd, l->ldinfo_datasize));
- n1 = strlen ((char *) l->ldinfo_filename);
- printf (" %s %s\n",
- l->ldinfo_filename, l->ldinfo_filename + n1 + 1);
- if (next == 0)
- break;
- p += next;
- }
- }
- #else
- printf (_("\n"
- "ldinfo dump not supported in 32 bits environments\n"));
- #endif
- }
- }
- /* Dump a core file. */
- static void
- xcoff_dump_core (bfd *abfd)
- {
- struct external_core_dumpx hdr;
- unsigned int version;
- /* Read file header. */
- if (bfd_seek (abfd, 0, SEEK_SET) != 0
- || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
- {
- non_fatal (_("cannot core read header"));
- return;
- }
- version = bfd_h_get_32 (abfd, hdr.c_version);
- if (options[OPT_FILE_HEADER].selected)
- {
- printf (_("Core header:\n"));
- printf (_(" version: 0x%08x "), version);
- switch (version)
- {
- case CORE_DUMPX_VERSION:
- printf (_("(dumpx format - aix4.3 / 32 bits)"));
- break;
- case CORE_DUMPXX_VERSION:
- printf (_("(dumpxx format - aix5.0 / 64 bits)"));
- break;
- default:
- printf (_("unknown format"));
- break;
- }
- putchar ('\n');
- }
- if (version == CORE_DUMPX_VERSION)
- dump_dumpx_core (abfd, &hdr);
- else
- printf (_(" Unhandled magic\n"));
- }
- /* Dump an XCOFF file. */
- static void
- xcoff_dump (bfd *abfd)
- {
- /* We rely on BFD to decide if the file is a core file. Note that core
- files are only supported on native environment by BFD. */
- switch (bfd_get_format (abfd))
- {
- case bfd_core:
- xcoff_dump_core (abfd);
- break;
- default:
- xcoff_dump_obj (abfd);
- break;
- }
- }
- /* Vector for xcoff. */
- const struct objdump_private_desc objdump_private_desc_xcoff =
- {
- xcoff_help,
- xcoff_filter,
- xcoff_dump,
- options
- };
|