Author Topic: How can I find the .data segment? (elf out)  (Read 15691 times)

nobody

  • Guest
How can I find the .data segment? (elf out)
« on: December 29, 2008, 06:57:41 AM »
Just for fun, I'm trying to write a malloc in assembler, under linux with a 686 kernel. I want to use the sys_brk call for this, but to do so I need the absolute address of the .data segment. Is there a constant or something that will give me the start of the .data segment? Once I've got that I was thinking I would find its absolute address with GOT trickery, then resize the .data segment with sys_brk and go from there.

Thanks, RiRi

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How can I find the .data segment? (elf out)
« Reply #1 on: December 29, 2008, 11:19:20 PM »
S'pose you had the address of the start of the data segment - it's 0x804A123, say... What would you do with it?

There are fields in the header which would allow you to calculate this. (I've been told that the header doesn't load, but my experience is that it does - at 0x8048000 - and you can read it perfectly well) But... if you do sys_brk with ebx=0, it ought to return the *end* of the data segment (including .bss?), which might be more use. There's an "issue" with this - some (older?) kernels round this up to the nearest page, other (newer?) kernels return an "exact" value. My experience is that we *can* read/write(?)  to the end of the page, beyond what sys_brk says. This is *not* what's documented in "man 2 brk"! You'll have to experiment to find out just what really happens, probably.

xor ebx, ebx
mov eax, __NR_brk ; 45
int 80h
mov [original_break], eax
mov ebx, eax
add ebx, DELTA
mov eax, __NR_brk ; 45
int 80h
mov [new_break], eax

That should give you some memory of size DELTA (64k seems like a "lot" of memory to me, but you probably want more) that you can divide up into smaller chunks with malloc. When it's exhausted, do it again...

mov ebx, [new_break]
add ebx, DELTA
mov eax, __NR_brk ; 45
int 80h

You may want separate "new_break" variables for each block, to assist with "free" (by far the more difficult part of the project, in my mind).

Jonathan Bartlett's got a malloc example in his "Programming From The Ground Up" book (Gas syntax), and a link to a more sophisticated version, IIRC.

I think Randy Hyde's latest HLA stdlib code has a thread-safe version (worse to translate than Gas! :) I think it uses sys_mmap rather than sys_brk to get its "chunks".

As you probably know, malloc/free is a pretty complicated subject. How much fun do you wanna have? :)

Best,
Frank