Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

392
Visualizações
Calcule el punto de entrada de un archivo ELF como una dirección física (compensación desde 0)

Estoy construyendo un emulador RISC-V que básicamente carga un archivo ELF completo en la memoria.

Hasta ahora, usé los binarios de prueba precompilados que proporcionó la fundación risc-v, que convenientemente tenían un punto de entrada exactamente al comienzo de la sección .text .

Por ejemplo:

 > riscv32-unknown-elf-objdump ../riscv32i-emulator/tests/simple -d ../riscv32i-emulator/tests/simple: file format elf32-littleriscv Disassembly of section .text.init: 80000000 <_start>: 80000000: 0480006f j 80000048 <reset_vector> ...

Al iniciar este proyecto, no sabía mucho sobre los archivos ELF, así que asumí que el punto de entrada de cada ELF es exactamente el mismo que el inicio de la sección .text .

El problema surgió cuando compilé mis propios binarios, descubrí que el punto de entrada real no siempre es el mismo que el inicio de la sección .text , pero podría estar en cualquier lugar dentro, como aquí:

 > riscv32-unknown-elf-objdump a.out -d a.out: file format elf32-littleriscv Disassembly of section .text: 00010074 <register_fini>: 10074: 00000793 li a5,0 10078: 00078863 beqz a5,10088 <register_fini+0x14> 1007c: 00010537 lui a0,0x10 10080: 43850513 addi a0,a0,1080 # 10438 <__libc_fini_array> 10084: 3a00006f j 10424 <atexit> 10088: 00008067 ret 0001008c <_start>: 1008c: 00002197 auipc gp,0x2 10090: cec18193 addi gp,gp,-788 # 11d78 <__global_pointer$> ...

Entonces, después de leer más sobre los archivos ELF, descubrí que la dirección del punto de entrada real la proporciona la entrada Entry en el encabezado de ELF:

 > riscv32-unknown-elf-readelf a.out -h | grep Entry Entry point address: 0x1008c

El problema ahora es que esta dirección no es la dirección real en el archivo (compensada desde 0) sino una dirección virtual, por lo que, obviamente, si configuro el contador del programa de mi emulador en esta dirección, el emulador fallará.

Leyendo un poco más, escuché a la gente hablar sobre cálculos con respecto a las compensaciones de los encabezados del programa y otras cosas, pero nadie tenía una respuesta concreta.

Mi pregunta es: ¿cuál es la "fórmula" real de cómo obtiene exactamente la dirección del punto de entrada del procedimiento _start como un desplazamiento del byte 0?

Para que quede claro, mi emulador no es compatible con la memoria virtual y el binario es lo único que se carga en la memoria de mi emulador, por lo que no tengo uso para la abstracción de la memoria virtual. Solo quiero cada dirección de memoria como dirección física en el disco.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Mi pregunta es: ¿cuál es la "fórmula" real de cómo obtiene exactamente la dirección del punto de entrada del procedimiento _start como un desplazamiento del byte 0?

Primero, olvídate de las secciones . Sólo los segmentos importan en tiempo de ejecución .

En segundo lugar, use readelf -Wl para buscar segmentos. Le dicen exactamente qué parte del archivo ( [.p_offset, .p_offset + .p_filesz) ) va a qué región en memoria ( [.p_vaddr, .p_vaddr + .p_memsz) ).

El cálculo exacto de "en qué desplazamiento del archivo reside _start " es:

  1. Encuentre Elf32_Phdr que "cubre" la dirección contenida en Elf32_Ehdr.e_entry .
  2. Usando ese phdr , el desplazamiento del archivo de _start es: ehdr->e_entry - phdr->p_vaddr + phdr->p_offset .

Actualizar:

Entonces, ¿siempre estoy buscando el primer encabezado del programa?

No.

¿También por "cubiertas" quiere decir que el 1er phdr-> p_vaddr siempre es igual a e_entry?

No.

Está buscando el encabezado del programa (que describe la relación entre los datos en memoria y en archivo) que se superpone a ehdr->e_entry en la memoria. Es decir, está buscando el segmento para el que phdr->p_vaddr <= ehdr->e_entry && ehdr->e_entry < phdr->p_vaddr + phdr->p_memsz . Este segmento suele ser el primero, pero eso no está garantizado de ninguna manera. Véase también esta respuesta .

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda