diff options
author | Andrew Geissler <andrewg@us.ibm.com> | 2015-02-03 10:22:31 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-02-11 16:16:06 -0600 |
commit | 4cc2019545300c360258b5d60e358ce91cc13efd (patch) | |
tree | 29a7efc789d76446663f247a22bf634867b9e889 | |
parent | e83759d6aa90999933318155772b50a8af679ec6 (diff) | |
download | blackbird-hostboot-4cc2019545300c360258b5d60e358ce91cc13efd.tar.gz blackbird-hostboot-4cc2019545300c360258b5d60e358ce91cc13efd.zip |
gcc-4.9 support in Hostboot - tracehash fix
Change-Id: I46505bd6bddfdf4fb0f2dccc7c78a382431fc63d
RTC: 120455
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15520
Tested-by: Jenkins Server
Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r-- | src/build/linker/linker.C | 4 | ||||
-rw-r--r-- | src/build/mkrules/cflags.env.mk | 10 | ||||
-rw-r--r-- | src/build/trace/tracehash.c | 264 |
3 files changed, 262 insertions, 16 deletions
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C index d4f19d8e5..af5b7c543 100644 --- a/src/build/linker/linker.C +++ b/src/build/linker/linker.C @@ -31,7 +31,11 @@ // #include <stdint.h> #include <stdlib.h> + +#define PACKAGE 1 +#define PACKAGE_VERSION 1 #include <bfd.h> + #include <iostream> #include <iomanip> #include <fstream> diff --git a/src/build/mkrules/cflags.env.mk b/src/build/mkrules/cflags.env.mk index 5a3c7e122..8ca32b1b7 100644 --- a/src/build/mkrules/cflags.env.mk +++ b/src/build/mkrules/cflags.env.mk @@ -5,9 +5,9 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2014 -# [+] International Business Machines Corp. +# Contributors Listed Below - COPYRIGHT 2013,2015 # [+] Google Inc. +# [+] International Business Machines Corp. # # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -38,11 +38,11 @@ endif COMMONFLAGS += $(OPT_LEVEL) -nostdlib CFLAGS += $(COMMONFLAGS) -mcpu=power7 -nostdinc -g -mno-vsx -mno-altivec\ -Wall -Werror -mtraceback=no -pipe \ - -ffunction-sections -fdata-sections -ffreestanding -ASMFLAGS += $(COMMONFLAGS) -mcpu=power7 + -ffunction-sections -fdata-sections -ffreestanding -mbig-endian +ASMFLAGS += $(COMMONFLAGS) -mcpu=power7 -mbig-endian CXXFLAGS += $(CFLAGS) -nostdinc++ -fno-rtti -fno-exceptions -Wall \ -fuse-cxa-atexit -LDFLAGS += --nostdlib --sort-common $(COMMONFLAGS) +LDFLAGS += --nostdlib --sort-common -EB $(COMMONFLAGS) INCFLAGS = $(addprefix -I, $(INCDIR) ) ASMINCFLAGS = $(addprefix $(lastword -Wa,-I), $(INCDIR)) diff --git a/src/build/trace/tracehash.c b/src/build/trace/tracehash.c index 74dcd713f..d28920fe7 100644 --- a/src/build/trace/tracehash.c +++ b/src/build/trace/tracehash.c @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -44,7 +46,9 @@ */ #define _POSIX_C_SOURCE 200809L #define _GNU_SOURCE - +// Next 2 lines required by new BFD binutils package +#define PACKAGE 1 +#define PACKAGE_VERSION 1 #include <bfd.h> #include <stdio.h> #include <stdlib.h> @@ -177,8 +181,12 @@ char* format_content = NULL; /** Keep the full strings in the code rather than reduce to format strings. */ int full_strings = 0; +uint32_t *in_sect_idx_mod = NULL; +uint32_t *out_sect_idx_mod = NULL; + ///--------- Forward Declarations ------------------/// void create_sections(bfd*, asection*, void*); +void fixup_groups(bfd*, asection*, void*); void copy_relocs(bfd*, asection*, void*); void copy_content(bfd*, asection*, void*); char* create_format_string(const char*); @@ -192,6 +200,9 @@ void parse_traceinfo_sections(bfd*, asection*, void*); int check_hash_collision(ahash_string_list*); void write_hash_file(const char*); + +void determine_section_index_offsets(bfd*, bfd*); + ///--------- End Forward Declarations --------------/// /** @fn main @@ -220,6 +231,15 @@ int main(int argc, char** argv) bfd* outFile = bfd_openw(outFileName, bfd_get_target(inFile)); CHECK_NONNULL(outFile); + // Set Format + bfd_set_format(outFile,bfd_get_format(inFile)); + + // Set start address and file flags + bfd_set_start_address(outFile,bfd_get_start_address(inFile)); + flagword flags = bfd_get_file_flags(inFile); + flags &= bfd_applicable_file_flags (outFile); + bfd_set_file_flags(outFile,flags); + // Copy header data from .o.trace file. CHECK_ERR(bfd_set_arch_mach(outFile, bfd_get_arch(inFile), bfd_get_mach(inFile))); @@ -232,12 +252,13 @@ int main(int argc, char** argv) // Copy over other sections to new file. bfd_map_over_sections(inFile, create_sections, outFile); - // Create hash-string section. - create_hashstring_section(outFile); // Copy ELF private header. CHECK_ERR(bfd_copy_private_header_data(inFile, outFile)); + // Create hash-string section. + create_hashstring_section(outFile); + // Filter symbol table and add to destination file. symcount = filter_symtab(symsize, symcount); bfd_set_symtab(outFile, symtab, symcount); @@ -257,11 +278,133 @@ int main(int argc, char** argv) // Copy additional private BFD data and close file. CHECK_ERR(bfd_copy_private_bfd_data(inFile, outFile)); + + // Calcuate and store section offsets in preperation + // for the fixup_groups call + determine_section_index_offsets(inFile,outFile); + + bfd_map_over_sections(outFile, fixup_groups, inFile); bfd_close(outFile); + bfd_close(inFile); return 0; } + +/** @fn group_symbol + * + * Return a pointer to the symbol used as a signature for input group + * + * @param[in] group - Group section we are getting symbol for + * + * @return Pointer to the symbol for input group + */ +static asymbol * group_symbol (asection *group) +{ + + // Determine the proper offset to read the sh_info and then + // return the proper symbol + // See bfd_elf_section_data structure for offset info + uint32_t offset = sizeof(unsigned int) + + sizeof(unsigned int) + + sizeof(bfd_vma) + + sizeof(bfd_vma) + + sizeof(file_ptr) + + sizeof(bfd_size_type) + + sizeof(unsigned int); + + void *ptr_sym_offset = group->used_by_bfd + offset; + return origsymtab[(*(unsigned int *)ptr_sym_offset) - 1]; +} + +/** @fn fixup_groups + * + * This function will update the index values contained within + * the group data. This index value points to the section which + * are a part of the group. When we remove the trace sections, + * this index does not get updated correctly by BFD + * + * @param[in] newFile - The new BFD file we've generated + * @param[in] s - The group section we're updating + * @param[in] param - The original input BFD file + * + * @return N/A + */ +void fixup_groups(bfd* newFile, asection* s, void* param) +{ + bfd* origFile = (bfd*)param; + + if (bfd_get_section_flags(newFile, s) & SEC_GROUP) + { + bfd_byte *buf = NULL; + + // Using newFile looks a little weird here but there is a correlation + // between newFile and s that requires us to use it here. It doesn't + // matter since the section data was copied directly over into newFile. + CHECK_ERR(bfd_malloc_and_get_section(newFile,s,&buf)); + + uint32_t *group_val_ptr = (uint32_t *)buf; + + // First uint32_t is a flag then we get into the section indexes + group_val_ptr++; + + for(size_t i=1;i<((bfd_get_section_size(s))/sizeof(uint32_t)); + i++,group_val_ptr++) + { + uint32_t group_val = 0; + if(newFile->xvec->byteorder == BFD_ENDIAN_BIG) + { + group_val = be32toh(*group_val_ptr); + } + else + { + group_val = le32toh(*group_val_ptr); + } + uint32_t mod_index = group_val - in_sect_idx_mod[group_val]; + + // Find the section name in the original file using the index + asection *search = origFile->sections; + + while((search != NULL) + &&(search->index != mod_index)) + { + search=search->next; + } + + if(search == NULL) + { + printf ("Symbol not found so we gotta error out\n"); + exit(-1); + } + + // Now find that section in the new file + asection *new_search = bfd_get_section_by_name( + newFile,search->name); + CHECK_NONNULL(new_search); + + // Now add on the mod + mod_index = new_search->index + + out_sect_idx_mod[new_search->index]; + + // Now point the group index to that symbol in the new file + if(newFile->xvec->byteorder == BFD_ENDIAN_BIG) + { + *group_val_ptr = htobe32(mod_index); + } + else + { + *group_val_ptr = htole32(mod_index); + } + } + + CHECK_ERR(bfd_set_section_contents(newFile,s,buf,0, + bfd_get_section_size(s))); + + free(buf); + } + +} + /** @fn create_sections * * Creates a section in the result file based from the corresponding @@ -275,18 +418,32 @@ int main(int argc, char** argv) void create_sections(bfd* inFile, asection* s, void* param) { bfd* outFile = (bfd*)param; + asymbol *gsym = NULL; // Clear output-file section reference in the source section. s->output_section = NULL; - // Skip traceParseInfo and ELF-groups sections. - if (NULL != strstr(s->name, PARSEINFO_SECTION_NAME)) { return; } - if (bfd_get_section_flags(inFile, s) & SEC_GROUP) { return; } + // Skip traceParseInfo sections + if (NULL != strstr(s->name, PARSEINFO_SECTION_NAME)) + { + return; + } + + // if group points to traceParseInfo section then don't copy over + if (bfd_get_section_flags(inFile, s) & SEC_GROUP) + { + gsym = group_symbol (s); + if (NULL != strstr(gsym->name, PARSEINFO_SECTION_NAME)) + { + return; + } + } - // Create result section. + // Create section. asection* new_s = - bfd_make_section_anyway_with_flags(outFile, s->name, - bfd_get_section_flags(inFile, s)); + bfd_make_section_anyway_with_flags(outFile, s->name, + bfd_get_section_flags(inFile, s)); + CHECK_NONNULL(new_s); // Copy section sizes. @@ -299,10 +456,35 @@ void create_sections(bfd* inFile, asection* s, void* param) // Copy alignment and private data. CHECK_ERR(bfd_set_section_alignment(outFile, new_s, bfd_section_alignment(inFile, s))); - CHECK_ERR(bfd_copy_private_section_data(inFile, s, outFile, new_s)); + + new_s->entsize = s->entsize; // Hook up output_section reference to source section. s->output_section = new_s; + s->output_offset = 0; + + if (gsym != NULL) + { + if (inFile->xvec->flavour == bfd_target_elf_flavour) + { + // Add the magic number and update the group id + // for this section to point to the group + // symbol + // Binutils 2.24 BFD requires an offset of 176 + // Binutils 2.22 BFD requires an offset of 168 + // So we're just going to key off a define that's only in 2.24 + // TODO RTC 123492 +#ifdef bfd_find_nearest_line_discriminator + uint32_t offset = 176; +#else + uint32_t offset = 168; +#endif + void *ptr_sym_offset = s->used_by_bfd + offset; + asymbol **tsym = (asymbol **)ptr_sym_offset; + *tsym = gsym; + } + } + CHECK_ERR(bfd_copy_private_section_data(inFile,s,outFile,new_s)); } /** @fn copy_relocs @@ -597,6 +779,7 @@ size_t filter_symtab(size_t symsize, size_t symcount) // Insert the symbol for the format string section. new_table[newcount++] = hash_section->symbol; + new_table[newcount] = NULL; symtab = new_table; return newcount; @@ -915,3 +1098,62 @@ void write_hash_file(const char* file) fclose(hash_file); } + +/** @fn determine_section_index_offsets + * + * The RELOC sections are not officially counted in any of the BFD count + * interfaces we have so we have to go through both the BFD's and manually + * figure out the section count. + * We then use this information later to update the group indexes which + * reference the count that includes the RELOC sections. + * + * @param[in] inFile - Input BFD file. + * @param[in] outFile - Output BFD file. + * + * @return N/A + */ +void determine_section_index_offsets(bfd* inFile, bfd* outFile) +{ + asection *sect = NULL; + + // Start at 1 to skip the initial NULL section in all BFD's + int section_index=1; + int section_offset=1; + + for(sect=inFile->sections; sect != NULL; sect = sect->next,section_index++) + { + in_sect_idx_mod = (uint32_t *)realloc(in_sect_idx_mod, + (section_index +1)* + sizeof(uint32_t)); + in_sect_idx_mod[section_index] = section_offset; + + if (bfd_get_section_flags(inFile, sect) & SEC_RELOC) + { + section_index++; + section_offset++; + in_sect_idx_mod = (uint32_t *)realloc(in_sect_idx_mod, + (section_index +1)* + sizeof(uint32_t)); + in_sect_idx_mod[section_index] = section_offset; + } + } + + section_index=1; + section_offset=1; + + for(sect=outFile->sections; sect != NULL; sect = sect->next,section_index++) + { + out_sect_idx_mod = (uint32_t *)realloc(out_sect_idx_mod, + (sect->index +1)* + sizeof(uint32_t)); + + out_sect_idx_mod[sect->index] = section_offset; + + if (bfd_get_section_flags(outFile, sect) & SEC_RELOC) + { + section_index++; + section_offset++; + } + + } +} |