Добавить незаконченные символы в генерацию эльф объектиников

This commit is contained in:
rexim 2024-01-20 13:58:12 +07:00
parent d82637ef24
commit 28a3c04fbb

View File

@ -18,14 +18,16 @@ const ЭЛЬФ64_МПБ_СИС5_ИДЕНТ: &[u8] = // e_ident
type Эльф64Пол = u16; // Elf64_Half
type Эльф64Слово = u32; // Elf64_Word
type Эльф64ХСлово = u64; // Elf64_XWord
type Эльф64Хслово = u64; // Elf64_Xword
type Эльф64Адрес = u64; // Elf64_Addr
type Эльф64Смещ = u64; // Elf64_Off
type Эльф64Секция = u16; // Elf64_Section
const ЭЛЬФ_ТЕКУЩАЯ_ВЕРСИЯ: usize = 1; // EV_CURRENT
const ЭЛЬФ64_РАЗМЕР_ЭЛЬФ_ЗАГОЛОВКА: usize = 64; // sizeof(Elf64_Ehdr)
const ЭЛЬФ64_РАЗМЕРРОГ_ЗАГОЛОВКА: usize = 56; // sizeof(Elf64_Phdr)
const ЭЛЬФ64_РАЗМЕР_СЕКЦ_ЗАГОЛОВКА: usize = 64; // sizeof(Elf64_Shdr)
const ЭЛЬФ64_РАЗМЕР_ЗАПИСИ_СИМВОЛА: usize = 24; // sizeof(Elf64_Sym)
enum ЭльфТип { // e_type
Перемещаемый = 1, // ET_REL
@ -333,8 +335,9 @@ fn выравнять_байты(байты: &mut Vec<u8>, выравниван
#[derive(Clone, Copy)]
enum ТипСекции { // sh_type
Пустая = 0, // SHT_NULL
ТаблицаСтрок = 3, // SHT_STRTAB
Пустая = 0, // SHT_NULL
ТаблицаСимволов = 2, // SHT_SYMTAB
ТаблицаСтрок = 3, // SHT_STRTAB
}
struct Секция {
@ -354,6 +357,19 @@ impl Секция {
}
}
fn таблица_символов<'ы>(символы: &[Символ], смещения_строк: &HashMap<&'ы str, usize>) -> Секция {
let mut байты: Vec<u8> = Vec::new();
for символ in символы {
байты.extend(символ.байты(смещения_строк));
}
Секция {
имя: ".symtab",
тип: ТипСекции::ТаблицаСимволов,
байты,
выравнивание: 1,
}
}
fn таблица_строк<'ы>(строки: &[&'ы str]) -> (Секция, HashMap<&'ы str, usize>) {
let mut байты: Vec<u8> = Vec::new();
let mut смещения_строк: HashMap<&str, usize> = HashMap::new();
@ -375,14 +391,60 @@ impl Секция {
let mut байты: Vec<u8> = Vec::new();
байты.extend((*смещения_строк.get(self.имя).unwrap() as Эльф64Слово).to_le_bytes()); // sh_name
байты.extend((self.тип as Эльф64Слово).to_le_bytes()); // sh_type
байты.extend((0 as Эльф64ХСлово).to_le_bytes()); // sh_flags
байты.extend((0 as Эльф64Хслово).to_le_bytes()); // sh_flags
байты.extend((0 as Эльф64Адрес).to_le_bytes()); // sh_addr
байты.extend(начало_секции.to_le_bytes()); // sh_offset
байты.extend((self.байты.len() as Эльф64ХСлово).to_le_bytes()); // sh_size
байты.extend((self.байты.len() as Эльф64Хслово).to_le_bytes()); // sh_size
байты.extend((0 as Эльф64Слово).to_le_bytes()); // sh_link
байты.extend((0 as Эльф64Слово).to_le_bytes()); // sh_info
байты.extend((self.выравнивание as Эльф64ХСлово).to_le_bytes()); // sh_addralign
байты.extend((0 as Эльф64ХСлово).to_le_bytes()); // sh_entsize
байты.extend((self.выравнивание as Эльф64Хслово).to_le_bytes()); // sh_addralign
байты.extend((0 as Эльф64Хслово).to_le_bytes()); // sh_entsize
байты
}
}
#[derive(Clone, Copy)]
enum ТипСимвола {
Никакой = 0, // STT_NOTYPE
Функция = 2, // STT_FUNC
Секция = 3, // STT_SECTION
}
#[derive(Clone, Copy)]
enum СвязьСимвола {
Локальная = 0, // STB_LOCAL
Глобальная = 1, // STB_GLOBAL
}
fn символ_инфо(связь: СвязьСимвола, тип: ТипСимвола) -> u8 { // ELF64_ST_INFO(bind, type)
((связь as u8)<<4) + ((тип as u8)&0xF)
}
struct Символ {
имя: &'static str, // st_name
тип: ТипСимвола, // st_info (st_type)
связь: СвязьСимвола, // st_info (st_bind)
индекс_секции: usize, // st_shndx
}
impl Символ {
fn пустой() -> Символ {
Символ {
имя: "",
тип: ТипСимвола::Никакой,
связь: СвязьСимвола::Локальная,
индекс_секции: 0,
}
}
fn байты<'ы>(&self, смещения_строк: &HashMap<&'ы str, usize>) -> Vec<u8> {
let mut байты = Vec::new();
байты.extend((*смещения_строк.get(self.имя).unwrap() as Эльф64Слово).to_le_bytes()); // st_name
байты.extend(символ_инфо(self.связь, self.тип).to_le_bytes()); // st_info
байты.extend((0 as u8).to_le_bytes()); // st_other
байты.extend((self.индекс_секции as Эльф64Секция).to_le_bytes()); // st_shndx
байты.extend((0 as Эльф64Адрес).to_le_bytes()); // st_value
байты.extend((0 as Эльф64Хслово).to_le_bytes()); // st_size
байты
}
}
@ -398,6 +460,7 @@ pub fn сгенерировать_объектный_файл(путь_к_фай
]);
let индексаблицы_строк = секции.len();
секции.push(секцияаблицы_строк);
секции.push(Секция::таблица_символов(&[Символ::пустой()], &смещения_строк));
let mut байты: Vec<u8> = Vec::new();
байты.extend(ЭЛЬФ64_МПБ_СИС5_ИДЕНТ); // e_ident