2014-03-03 21 views
3

我的問題是關於bfd的,以及在以下代碼中段的數量是如何工作的。下面顯示了bfd結構的gdb調試器內部的代碼和轉儲以及它內部的部分結構。我還包括了下面bfd和bfd->部分的數據結構定義。我的問題是:爲什麼當我運行這段代碼時(可執行文件被稱爲getsections):getsections getsections.o(因此將它傳遞給自己的目標文件) - 爲什麼部分結構是空白的(全爲零),如果你看看bfd- > section_count,它的號碼是4218960?如果您使用Linux命令:objdump -h getsections.o,它將顯示14個部分(.text,.data,.bss,.rodata,.debug_info,.debug_abbrev,.debug_loc,.debug_aranges,.debug_line,.debug_str ,.評論,.comment.SUSE.OPTS,.note-GNU-stack,.eh_frame)。我已經閱讀了我在網上的BFD文檔中可以找到的內容,並且我不確定我在這裏做了什麼錯誤,因爲我的目標文件結構遠不及objdump(14節)所看到的結果。任何幫助表示讚賞。謝謝。使用bfd數據結構的目標文件中的段的數量

unsigned int number_of_sections(bfd *abfd) 
{ 
    unsigned int numSections = 0; 
    numSections = bfd_count_sections(abfd); 
    return numSections; 
} 

int main (int argc, char *argv[]) 
{ 
    bfd *ibfd = NULL; 
    char filename[80]; 
    char *fptr = &filename[0]; 
    unsigned int numSections = 0; 

    if (argc < 2) 
    { 
     printf("Argc < 2\n"); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     bfd_init(); 
     printf("filename = %s\n", argv[1]); 
     ibfd = bfd_openr(argv[1], NULL); 
     numSections = number_of_sections(ibfd); 
     printf("num sections = %d\n", numSections); 
     bfd_close(ibfd); 
    } 
    return 1; 
} 

設置在number_of_sections()斷點時,BFD的轉儲將產生以下:

(gdb) print abfd 
$1 = (bfd *) 0x85c010 
(gdb) print *abfd 
$2 = {filename = 0x0, xvec = 0x7fffffffe06f, iostream = 0x7fff20 <bfd_elf64_x86_64_vec> "\211\345X", cacheable = (unknown: 8773984), target_defaulted = false, lru_prev = 0x7f6d40 <cache_iovec>, lru_next = 0x85c010, where = 8765456, opened_once = false, mtime_set = false, mtime = 0, ifd = 0, format = bfd_unknown, direction = read_direction, flags = 0, origin = 0, output_has_begun = false, sections = 0x85d180, section_count = 4218960, start_address = 8769872, symcount = 251, outsymbols = 0x130, arch_info = 0x0, arelt_data = 0x0, my_archive = 0x0, next = 0x0, archive_head = 0x0, has_armap = false, link_next = 0x0, archive_pass = 8673856, tdata = {aout_data = 0x0, aout_ar_data = 0x0, oasys_obj_data = 0x0, oasys_ar_data = 0x0, coff_obj_data = 0x0, pe_obj_data = 0x0, xcoff_obj_data = 0x0, ecoff_obj_data = 0x0, ieee_data = 0x0, ieee_ar_data = 0x0, srec_data = 0x0, tekhex_data = 0x0, elf_obj_data = 0x0, nlm_obj_data = 0x0, bout_data = 0x0, sun_core_data = 0x0, trad_core_data = 0x0, som_data = 0x0, hpux_core_data = 0x0, hppabsd_core_data = 0x0, sgi_core_data = 0x0, lynx_core_data = 0x0, osf_core_data = 0x0, cisco_core_data = 0x0, versados_data = 0x0, any = 0x0}, usrdata = 0x0, memory = {chunk_size = 0, chunk = 0x0, object_base = 0x0, next_free = 0x0, chunk_limit = 0x0, temp = {tempint = 0, tempptr = 0x0}, alignment_mask = 0, chunkfun = 0x85c140, freefun = 0x7, extra_arg = 0x21, use_extra_arg = 0, maybe_empty_object = 0, alloc_failed = 0}} 

的abfd-的轉儲>部分看起來像有什麼也沒有:

(gdb) print *(abfd->sections) 
$4 = {name = 0x0, index = 0, next = 0x0, flags = 0, vma = 0, user_set_vma = false, lma = 0, _cooked_size = 0, _raw_size = 0, output_offset = 0, output_section = 0x0, alignment_power = 0, relocation = 0x0, orelocation = 0x0, reloc_count = 0, filepos = 0, rel_filepos = 0, line_filepos = 0, userdata = 0x0, contents = 0x0, lineno = 0x0, lineno_count = 0, moving_line_filepos = 0, target_index = 0, used_by_bfd = 0x0, constructor_chain = 0x0, owner = 0x0, reloc_done = false, symbol = 0x0, symbol_ptr_ptr = 0x0, link_order_head = 0x0, link_order_tail = 0x0} 

bfd結構看起來像:

struct _bfd 
{ 
/* The filename the application opened the BFD with. */ 
CONST char *filename;     

/* A pointer to the target jump table.    */ 
const struct bfd_target *xvec; 

/* To avoid dragging too many header files into every file that 
    includes `<<bfd.h>>', IOSTREAM has been declared as a "char 
    *", and MTIME as a "long". Their correct types, to which they 
    are cast when used, are "FILE *" and "time_t". The iostream 
    is the result of an fopen on the filename. */ 
char *iostream; 

/* Is the file descriptor being cached? That is, can it be closed as 
    needed, and re-opened when accessed later? */ 

boolean cacheable; 

/* Marks whether there was a default target specified when the 
    BFD was opened. This is used to select which matching algorithm 
    to use to choose the back end. */ 

boolean target_defaulted; 

/* The caching routines use these to maintain a 
    least-recently-used list of BFDs */ 

struct _bfd *lru_prev, *lru_next; 

/* When a file is closed by the caching routines, BFD retains 
    state information on the file here: */ 

file_ptr where;    

/* and here: (``once'' means at least once) */ 

boolean opened_once; 

/* Set if we have a locally maintained mtime value, rather than 
    getting it from the file each time: */ 

boolean mtime_set; 

/* File modified time, if mtime_set is true: */ 

long mtime;   

/* Reserved for an unimplemented file locking extension.*/ 

int ifd; 

/* The format which belongs to the BFD. (object, core, etc.) */ 

bfd_format format; 

/* The direction the BFD was opened with*/ 

enum bfd_direction {no_direction = 0, 
        read_direction = 1, 
        write_direction = 2, 
        both_direction = 3} direction; 

/* Format_specific flags*/ 

flagword flags;    

/* Currently my_archive is tested before adding origin to 
    anything. I believe that this can become always an add of 
    origin, with origin set to 0 for non archive files. */ 

file_ptr origin;    

/* Remember when output has begun, to stop strange things 
    from happening. */ 
boolean output_has_begun; 

/* Pointer to linked list of sections*/ 
struct sec *sections; 

/* The number of sections */ 
unsigned int section_count; 

/* Stuff only useful for object files: 
    The start address. */ 
bfd_vma start_address; 

/* Used for input and output*/ 
unsigned int symcount; 

/* Symbol table for output BFD (with symcount entries) */ 
struct symbol_cache_entry **outsymbols;    

/* Pointer to structure which contains architecture information*/ 
const struct bfd_arch_info *arch_info; 

/* Stuff only useful for archives:*/ 
PTR arelt_data;    
struct _bfd *my_archive;  /* The containing archive BFD. */ 
struct _bfd *next;   /* The next BFD in the archive. */ 
struct _bfd *archive_head; /* The first BFD in the archive. */ 
boolean has_armap;   

/* A chain of BFD structures involved in a link. */ 
struct _bfd *link_next; 

/* A field used by _bfd_generic_link_add_archive_symbols. This will 
    be used only for archive elements. */ 
int archive_pass; 

/* Used by the back end to hold private data. */ 

union 
    { 
    struct aout_data_struct *aout_data; 
    struct artdata *aout_ar_data; 
    struct _oasys_data *oasys_obj_data; 
    struct _oasys_ar_data *oasys_ar_data; 
    struct coff_tdata *coff_obj_data; 
    struct pe_tdata *pe_obj_data; 
    struct xcoff_tdata *xcoff_obj_data; 
    struct ecoff_tdata *ecoff_obj_data; 
    struct ieee_data_struct *ieee_data; 
    struct ieee_ar_data_struct *ieee_ar_data; 
    struct srec_data_struct *srec_data; 
    struct tekhex_data_struct *tekhex_data; 
    struct elf_obj_tdata *elf_obj_data; 
    struct nlm_obj_tdata *nlm_obj_data; 
    struct bout_data_struct *bout_data; 
    struct sun_core_struct *sun_core_data; 
    struct trad_core_struct *trad_core_data; 
    struct som_data_struct *som_data; 
    struct hpux_core_struct *hpux_core_data; 
    struct hppabsd_core_struct *hppabsd_core_data; 
    struct sgi_core_struct *sgi_core_data; 
    struct lynx_core_struct *lynx_core_data; 
    struct osf_core_struct *osf_core_data; 
    struct cisco_core_struct *cisco_core_data; 
    struct versados_data_struct *versados_data; 
    PTR any; 
    } tdata; 

/* Used by the application to hold private data*/ 
PTR usrdata; 

/* Where all the allocated stuff under this BFD goes */ 
struct obstack memory; 
}; 

和bfd->部分結構(SEC結構)是這樣的:

typedef struct sec 
{ 
    /* The name of the section; the name isn't a copy, the pointer is 
    the same as that passed to bfd_make_section. */ 

    CONST char *name; 

    /* Which section is it; 0..nth.  */ 

    int index; 

    /* The next section in the list belonging to the BFD, or NULL. */ 

    struct sec *next; 

    /* The field flags contains attributes of the section. Some 
     flags are read in from the object file, and some are 
     synthesized from other information. */ 

    flagword flags; 

#define SEC_NO_FLAGS 0x000 

    /* Tells the OS to allocate space for this section when loading. 
     This is clear for a section containing debug information 
     only. */ 
#define SEC_ALLOC  0x001 

    /* Tells the OS to load the section from the file when loading. 
     This is clear for a .bss section. */ 
#define SEC_LOAD  0x002 

    /* The section contains data still to be relocated, so there is 
     some relocation information too. */ 
#define SEC_RELOC  0x004 

#if 0 /* Obsolete ? */ 
#define SEC_BALIGN  0x008 
#endif 

    /* A signal to the OS that the section contains read only 
     data. */ 
#define SEC_READONLY 0x010 

    /* The section contains code only. */ 
#define SEC_CODE  0x020 

    /* The section contains data only. */ 
#define SEC_DATA  0x040 

    /* The section will reside in ROM. */ 
#define SEC_ROM  0x080 

    /* The section contains constructor information. This section 
     type is used by the linker to create lists of constructors and 
     destructors used by <<g++>>. When a back end sees a symbol 
     which should be used in a constructor list, it creates a new 
     section for the type of name (e.g., <<__CTOR_LIST__>>), attaches 
     the symbol to it, and builds a relocation. To build the lists 
     of constructors, all the linker has to do is catenate all the 
     sections called <<__CTOR_LIST__>> and relocate the data 
     contained within - exactly the operations it would peform on 
     standard data. */ 
#define SEC_CONSTRUCTOR 0x100 

    /* The section is a constuctor, and should be placed at the 
     end of the text, data, or bss section(?). */ 
#define SEC_CONSTRUCTOR_TEXT 0x1100 
#define SEC_CONSTRUCTOR_DATA 0x2100 
#define SEC_CONSTRUCTOR_BSS 0x3100 

    /* The section has contents - a data section could be 
     <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be 
     <<SEC_HAS_CONTENTS>> */ 
#define SEC_HAS_CONTENTS 0x200 

    /* An instruction to the linker to not output the section 
     even if it has information which would normally be written. */ 
#define SEC_NEVER_LOAD 0x400 

    /* The section is a COFF shared library section. This flag is 
     only for the linker. If this type of section appears in 
     the input file, the linker must copy it to the output file 
     without changing the vma or size. FIXME: Although this 
     was originally intended to be general, it really is COFF 
     specific (and the flag was renamed to indicate this). It 
     might be cleaner to have some more general mechanism to 
     allow the back end to control what the linker does with 
     sections. */ 
#define SEC_COFF_SHARED_LIBRARY 0x800 

    /* The section is a common section (symbols may be defined 
     multiple times, the value of a symbol is the amount of 
     space it requires, and the largest symbol value is the one 
     used). Most targets have exactly one of these (which we 
    translate to bfd_com_section_ptr), but ECOFF has two. */ 
#define SEC_IS_COMMON 0x8000 

    /* The section contains only debugging information. For 
     example, this is set for ELF .debug and .stab sections. 
     strip tests this flag to see if a section can be 
     discarded. */ 
#define SEC_DEBUGGING 0x10000 

    /* The contents of this section are held in memory pointed to 
     by the contents field. This is checked by 
     bfd_get_section_contents, and the data is retrieved from 
     memory if appropriate. */ 
#define SEC_IN_MEMORY 0x20000 

/* End of section flags. */ 

    /* The virtual memory address of the section - where it will be 
     at run time. The symbols are relocated against this. The 
    user_set_vma flag is maintained by bfd; if it's not set, the 
    backend can assign addresses (for example, in <<a.out>>, where 
    the default address for <<.data>> is dependent on the specific 
    target and various flags). */ 

    bfd_vma vma; 
    boolean user_set_vma; 

    /* The load address of the section - where it would be in a 
     rom image; really only used for writing section header 
    information. */ 

    bfd_vma lma; 

    /* The size of the section in bytes, as it will be output. 
     contains a value even if the section has no contents (e.g., the 
     size of <<.bss>>). This will be filled in after relocation */ 

    bfd_size_type _cooked_size; 

    /* The original size on disk of the section, in bytes. Normally this 
    value is the same as the size, but if some relaxing has 
    been done, then this value will be bigger. */ 

    bfd_size_type _raw_size; 

    /* If this section is going to be output, then this value is the 
     offset into the output section of the first byte in the input 
     section. E.g., if this was going to start at the 100th byte in 
     the output section, this value would be 100. */ 

    bfd_vma output_offset; 

    /* The output section through which to map on output. */ 

    struct sec *output_section; 

    /* The alignment requirement of the section, as an exponent of 2 - 
     e.g., 3 aligns to 2^3 (or 8). */ 

    unsigned int alignment_power; 

    /* If an input section, a pointer to a vector of relocation 
     records for the data in this section. */ 

    struct reloc_cache_entry *relocation; 

    /* If an output section, a pointer to a vector of pointers to 
     relocation records for the data in this section. */ 

    struct reloc_cache_entry **orelocation; 

    /* The number of relocation records in one of the above */ 

    unsigned reloc_count; 

    /* Information below is back end specific - and not always used 
     or updated. */ 

    /* File position of section data */ 

    file_ptr filepos; 

    /* File position of relocation info */ 

    file_ptr rel_filepos; 

    /* File position of line data  */ 

    file_ptr line_filepos; 

    /* Pointer to data for applications */ 

    PTR userdata; 

    /* If the SEC_IN_MEMORY flag is set, this points to the actual 
     contents. */ 
    unsigned char *contents; 

    /* Attached line number information */ 

    alent *lineno; 

    /* Number of line number records */ 

    unsigned int lineno_count; 

    /* When a section is being output, this value changes as more 
     linenumbers are written out */ 

    file_ptr moving_line_filepos; 

    /* What the section number is in the target world */ 

    int target_index; 

    PTR used_by_bfd; 

    /* If this is a constructor section then here is a list of the 
     relocations created to relocate items within it. */ 

    struct relent_chain *constructor_chain; 

    /* The BFD which owns the section. */ 

    bfd *owner; 

    boolean reloc_done; 
    /* A symbol which points at this section only */ 
    struct symbol_cache_entry *symbol; 
    struct symbol_cache_entry **symbol_ptr_ptr; 

    struct bfd_link_order *link_order_head; 
    struct bfd_link_order *link_order_tail; 
} asection ; 

回答

2

我沒有嘗試你的程序。但是,我注意到它不會調用bfd_check_format。這是必需的。 BFD文檔並不總是清楚這些東西(改進值得歡迎!),所以當我需要處理BFD時,我通常最終會讀取示例程序,如objdump。

我的一個BFD測試開始:

fd = open (argv[1], O_RDONLY | O_CLOEXEC, 0); 
if (fd == -1) 
    die ("open"); 

abfd = bfd_fopen (argv[1], NULL, "r", fd); 

if (!bfd_check_format (abfd, bfd_object)) 
    { 
    bfd_close (abfd); 
    die ("bfd_check_format"); 
    } 
相關問題