From 1d2c9b7f8001c21c472c7da8a18739c3d48a5718 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 29 Aug 2013 19:41:23 +0800 Subject: Fix archive writer 1. align to even address 2. Fix the use of GElf_Ehdr and Elf32_Ehdr 3. Fix the header related --- rld-elf-types.h | 1 + rld-elf.cpp | 28 ++++++++++++++++++++++------ rld-files.cpp | 15 +++++++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/rld-elf-types.h b/rld-elf-types.h index c305976..c0da295 100644 --- a/rld-elf-types.h +++ b/rld-elf-types.h @@ -47,6 +47,7 @@ namespace rld typedef ::Elf_Kind elf_kind; typedef ::Elf_Scn elf_scn; typedef ::GElf_Ehdr elf_ehdr; + typedef ::Elf32_Ehdr elf32_ehdr; typedef ::GElf_Shdr elf_shdr; typedef ::GElf_Phdr elf_phdr; typedef ::Elf_Data elf_data; diff --git a/rld-elf.cpp b/rld-elf.cpp index 19aa1ab..8b2ac5e 100644 --- a/rld-elf.cpp +++ b/rld-elf.cpp @@ -1006,14 +1006,30 @@ namespace rld if (ehdr == 0) error ("gelf_newehdr"); - if (::gelf_getehdr (elf_, ehdr) == 0) + if (class_ == ELFCLASS32) + { + if((ehdr = (elf_ehdr*) ::elf32_getehdr (elf_)) == 0) + error ("elf32_getehdr"); + } + else if (::gelf_getehdr (elf_, ehdr) == 0) error ("gelf_getehdr"); - ehdr->e_type = type; - ehdr->e_machine = machinetype; - ehdr->e_flags = 0; - ehdr->e_ident[EI_DATA] = datatype; - ehdr->e_version = EV_CURRENT; + if (class_ == ELFCLASS32) + { + ((elf32_ehdr*)ehdr)->e_type = type; + ((elf32_ehdr*)ehdr)->e_machine = machinetype; + ((elf32_ehdr*)ehdr)->e_flags = 0; + ((elf32_ehdr*)ehdr)->e_ident[EI_DATA] = datatype; + ((elf32_ehdr*)ehdr)->e_version = EV_CURRENT; + } + else + { + ehdr->e_type = type; + ehdr->e_machine = machinetype; + ehdr->e_flags = 0; + ehdr->e_ident[EI_DATA] = datatype; + ehdr->e_version = EV_CURRENT; + } ::elf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY); } diff --git a/rld-files.cpp b/rld-files.cpp index 45a10bd..e10abb5 100644 --- a/rld-files.cpp +++ b/rld-files.cpp @@ -777,7 +777,7 @@ namespace rld archive::add_object (objects& objs, const char* path, off_t offset, size_t size) { const char* end = path; - while ((*end != '\0') && (*end != '/')) + while ((*end != '\0') && (*end != '/') && (*end != '\n')) ++end; std::string str; @@ -843,12 +843,16 @@ namespace rld { object& obj = *(*oi); const std::string& oname = basename (obj.name ().oname ()); - if (oname.length () > rld_archive_fname_size) + if (oname.length () >= rld_archive_fname_size) extended_file_names += oname + '\n'; } if (!extended_file_names.empty ()) { + if (extended_file_names.length () & 1) + { + extended_file_names += ' '; + } write_header ("//", 0, 0, 0, 0, extended_file_names.length ()); write (extended_file_names.c_str (), extended_file_names.length ()); } @@ -870,7 +874,7 @@ namespace rld * table if the file name is too long for the header. */ - if (oname.length () > rld_archive_fname_size) + if (oname.length () >= rld_archive_fname_size) { size_t pos = extended_file_names.find (oname + '\n'); if (pos == std::string::npos) @@ -879,10 +883,13 @@ namespace rld oss << '/' << pos; oname = oss.str (); } + else oname += '/'; - write_header (oname, 0, 0, 0, 0666, obj.name ().size ()); + write_header (oname, 0, 0, 0, 0666, (obj.name ().size () + 1) & ~1); obj.seek (0); copy_file (obj, *this); + if (obj.name ().size () & 1) + write ("\n", 1); } catch (...) { -- cgit v1.2.3