What is #object in **ELF** - x86-64

_thread int errno;
int get_errno() { return errno; }
And when i am disassembling it i am getting
for x86
.globl errno
.section .tbss,"awT",#nobits
.align 4
.type errno, #object
.size errno, 4
errno:
.zero 4
movl %fs:errno#tpoff, %eax
What does <.type errno , #object indicate here>
Please send a link of any valid document if you have

.type errno, #object sets the symbol type. It is represented in ELF as part of the st_info field in the Elf32_Sym or Elf64_Sym struct. <elf.h> uses STT_* constants for these symbols, and #object corresponds to STT_OBJECT. The constant values can be extracted from the st_info field using the ELF32_ST_TYPE and ELF64_ST_TYPE macros.
In the ELF specification, this is described in the Symbol Table chapter.

Related

Using local labels after switching sections inside a macro

Suppose, we have a macro that writes code into .data and .text sections:
%macro my_macro 0
[section .data]
table dd 1024
[section .text]
dec eax ; some commmands
%endmacro
global _start
section .text:
_start:
jmp .label_jump
my_macro
.label_jump:
mov eax, 1
mov ebx, 0
int 80h
If we have a local label placed after the macro call, it is impossible to jump to it above the macro call:
$ nasm test29.asm
test.asm:11: error: symbol `_start.label_jump' undefined
Is it possible to use the local labels in such circumstances?

Can't properly bind socket unless I pass a seemingly incorrect length

The code I've written doesn't work properly unless I pass a seemingly incorrect number to the length argument of bind. It kind of does work; after the accept call I can see it by running netstat, but the port is incorrect. I originally wrote the code in x86 assembly and I then wrote it in C. In both cases, it didn't work.
When calling the function socket, I passed AF_INET (2) as the domain, SOCK_STREAM (1) as the type, and TCP (6) as the protocol.
Here is the code, the one written in C:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main(void) {
unsigned int fd = socket(AF_INET, SOCK_STREAM, 6);
struct sockaddr_in thing = (struct sockaddr_in) {
.sin_family = AF_INET, //2 bytes
.sin_port = 0x2923, //2 bytes
.sin_addr = 0 //4 bytes
};
printf("%zu\n", sizeof thing);
bind(fd, (struct sockaddr*) &thing, 8); //Using 16 instead of 8 fixes the port problem, why?
listen(fd, 1);
accept(fd, 0, 0);
}
To me, 8 looks like the correct length to use. However, 16 seems to be the correct number to use. Why?
Here is the original code written in x86 NASM Assembly:
section .text
global _start
_start:
push byte 6
push byte 1
push byte 2
mov ecx, esp
mov ebx, 1 ;socket
mov eax, 102
int 80h
mov edi, eax ;file descriptor
push dword 0x00000000 ;4 bytes
push word 0x2923 ;2 bytes
push word 2 ;2 bytes
mov ecx, esp
push byte 8 ;Length argument, byte turned into 4 bytes in stack
push ecx
push edi
mov ecx, esp
mov ebx, 2 ;bind
mov eax, 102
int 80h
push byte 1
push edi
mov ecx, esp
mov ebx, 4 ;listen
mov eax, 102
int 80h
push byte 0
push byte 0
push edi
mov ecx, esp
mov ebx, 5 ;accept
mov eax, 102
int 80h
bind(fd, (struct sockaddr*) &thing, 8); //Using 16 instead of 8 fixes the port problem, why?
This code will fail with EINVAL (checked with Linux), but this error is simply ignored by your program. This means no explicit bind will be done.
listen(fd, 1);
accept(fd, 0, 0);
Since the explicit bind failed an implicit bind will be done, effectively meaning that the socket will listen on a random address. That's why it does not seem to work. netstat should show the random port here, not the actually intended one.
Look at the examples in the man page: https://man7.org/linux/man-pages/man2/bind.2.html.
You have to pass the size of the sockaddr_in structure.
bind(fd, (struct sockaddr*) &thing, sizeof(thing));
It's very likely that bind makes an internal check, to ensure that the 3rd parameter is indeed the size of the structure in the 2nd parameter
For AF_INET sockets bind surely knows that the 2nd parameter is a sockaddr_in instance, so it knows what value the 3rd parameter must be.
Really, there's nothing mysterious going on here.

GNU ASM .section directive not working/linker issue

I'm trying to move my _start function to 0x0, as it is the bootloader.
Flash ROM exists from 0x0 to the first 128MB (=1Gb), other memory is DDR3 RAM but we will map RAM to 0x80000000 to 0xFFFFFFFF.
The issue is with the directive .section ".vect", the _start address is not going into the .vect section, it is going into the .text section.
_start:
.section ".vect" /* I've tried .section .vect and I've tried moving above _start */
b ResetHandler
b UndefHandler
b SVC_Handler
b PrefetchAbortHandler
b DataAbortHandler
b NotUsedHandler
b IRQ_Handler
b FIQ_Handler
1:
b 1b /* Hang and don't return */
In my linker script, the MEMORY command and then the start of SECTIONS is:
MEMORY
{
vect (rx) : o = 0x0, l = 1M
rom (rx) : o = 1M, l = 127M
ram (wx) : o = 0x80000000, l = 0x80000000
}
SECTIONS
{
.vect : ALIGN(64)
{
. = 0x0;
*(.vect*)
VectTableEnd = .;
VectTableSize = SIZEOF(.vect);
} > vect
.... (.text, .bss, .data, .stack, etc are other SECTIONS entries)
}
But no matter what, the _start assembly function code gets shoved into the standard .text section, not at address 0x0. Does anyone know what I'm going wrong?
The code is targetted at bare-metal ARMv7A machines, compiled/linked with arm-none-eabi-as/ld
Cheers.
No surprises here if your _start label ends up in .text:
/* implicitly default section .text */
_start:
/* still the same section .text */
.section .vect
/* explicitly the section .vect */
b ResetHandler
You probably want to switch the section before defining the _start label to make that label end up in the intended section.
/* implicitly default section .text */
.section .vect
/* explicitly the section .vect */
_start:
b ResetHandler
Using the name _start as the symbol for a vector table is a bit weird (I would have expected a symbol like __vectors or vector_table), but that is beyond the scope of this question.

How to find the values of the arguments in socket programming in Assembly?

I am trying socket programming for ARM, however I am not able to understand how the values for the arguments are decided.
For example
this is the link for Azeria Labs
I understand that sys call for ARM register R7 gets it hence its 281 in this case and arguments are passed using R0, R1, R2, R3. But here how do you decide the values for R0(AF_INET) as 2 and R1(SOCK_STREAM) as 1 while creating socket(AF_INET, SOCK_STREAM, 0)
Finding system call was easy
$ grep socket /usr/include/asm/unistd-common.h
#define __NR_socket (__NR_SYSCALL_BASE+281)
#define __NR_socketpair (__NR_SYSCALL_BASE+288)
Similarly is there a way to find the values for the arguments?
I found an another resource which was for X86 Assembly which also has similar approach.
%assign SOCK_STREAM 1
%assign AF_INET 2
%assign SYS_socketcall 102
%assign SYS_SOCKET 1
%assign SYS_CONNECT 3
%assign SYS_SEND 9
%assign SYS_RECV 10
section .text
global _start
;--------------------------------------------------
;Functions to make things easier. :]
;--------------------------------------------------
_socket:
mov [cArray+0], dword AF_INET
mov [cArray+4], dword SOCK_STREAM
mov [cArray+8], dword 0
mov eax, SYS_socketcall
mov ebx, SYS_SOCKET
mov ecx, cArray
int 0x80
ret
Kindly let me know.
Thank you.
Linux alarmpi 4.4.34+ #3 Thu Dec 1 14:44:23 IST 2016 armv6l GNU/Linux

NASM local variables - are they, in fact, global macros?

I've been using the %local directive in NASM to define local variables and thus avoid typing [ebp - 8], [ebp - 24] etc. all the time.
However, I noticed that a local variable defined in one function between the preprocessor context %push and %pop is still available in the rest of the code, which may result in unexpected parsing errors.
Here, I've written a minimal example demonstrating the problem:
struc Rect
.left resd 1
.top resd 1
.width resd 1
.height resd 1
endstruc
%define RECT(x) g_rect + Rect. %+ x
segment .bss
g_rect resd 4
segment .text
; ================================================
function1:
%push
%stacksize flat
%assign %$localsize 0
%local width:dword ; defines local var "width"
push ebp
mov ebp, esp
sub esp, 4
pusha
; ...
popa
leave
ret
%pop
; ================================================
function2:
push ebp
mov ebp, esp
pusha
; ...
mov eax, RECT(height) ; OK
mov ebx, RECT(width) ; Parse error
; ...
popa
leave
ret
The exact error is:
nasm -f elf -d ELF_TYPE -g test.asm
test.asm:42: error: comma, colon, decorator or end of line expected after operand
Obviously, it happens because width is getting substituted with something else, and if I remove the local param definition, the problem goes away.
As you can see, the variable width is still available after the %pop. This doesn't look very local to me! I'd expect NASM to undefine width when the %pop is executed.
Is there a way to use %local but avoid these leaking macros? At the moment they act as a simple %define statement which is confusing.