st_mode of a symlink has weird value - symlink

I'm stat()'ing this symlink (on Kubuntu GNU/Linux 16.04), and am getting the weird value of 0100600 octal (33152 decimal). If I bitwise-and it with S_IFMT (which is 0170000 octal), I get 0600 octal. What does that mean? stat.h lists the following values:
/* File types. */
#define __S_IFDIR 0040000 /* Directory. */
#define __S_IFCHR 0020000 /* Character device. */
#define __S_IFBLK 0060000 /* Block device. */
#define __S_IFREG 0100000 /* Regular file. */
#define __S_IFIFO 0010000 /* FIFO. */
#define __S_IFLNK 0120000 /* Symbolic link. */
#define __S_IFSOCK 0140000 /* Socket. */
I'm expecting to see 0120000, not 0600 (all octal). What gives?

Based on #dave_thompson_085's observation: Indeed, stat() follows symlinks; I should be calling lstat() - which does exactly the same thing, but doesn't follow the link.

Related

_far _near _cdecl _pascal in migration from VC6 to VS2019

I'm migrating a project from VC6 to VS2019. As far as I know, _far _near are for the segmented memory model access, and _cdel _ pascal are for calling convention. All of them seem only existed in VC6 and older versions. For migration, is it safe to remove them like the #else block? Thanks!
Code:
/* 関数タイプ コンパイラ依存 */
#ifdef MSDOS
#ifdef _MSC_VER /* MS-C Ver.6.0以上 */
#define FAR _far
#define NEAR _near
#define CDECL _cdecl
#define LeafFunc _fastcall _near /* nearコール */
#define NearFunc _pascal _near /* nearコール */
#define FarLeafFunc _fastcall _far /* farコール */
#define FarFunc _pascal _far /* farコール */
#define register /* register宣言は無視 */
#else /* その他 */
#define FAR
#define NEAR
#define CDECL
#define LeafFunc
#define NearFunc
#define FarLeafFunc
#define FarFunc
#endif
NareFunc is used like the following code:
void NearFunc mmInit PT0() {
//...
}
EDIT: Thanks to 9dan. I've corrected _far and _near in the post.

Why is stat's st_size field offset 96 on 64bit OSX and can it be calculated?

Using the latest sources from apple's open source repo I have derived the following structure for the "stat" struct (in go syntax):
type timespec struct {
tv_sec int32
tv_nsec uint32
}
type stat64 struct {
st_dev int32 /* [XSI] ID of device containing file */
st_mode uint16 /* [XSI] Mode of file (see below) */
st_nlink uint16 /* [XSI] Number of hard links */
st_ino uint64 /* [XSI] File serial number */
st_uid uint32 /* [XSI] User ID of the file */
st_gid uint32 /* [XSI] Group ID of the file */
st_rdev int32 /* [XSI] Device ID */
st_atimespec timespec /* time of last access */
st_mtimespec timespec /* time of last data modification */
st_ctimespec timespec /* time of last status change */
st_birthtimespec timespec /* time of file creation(birth) */
st_size int64 /* [XSI] file size, in bytes */
st_blocks int64 /* [XSI] blocks allocated for file */
st_blksize int32 /* [XSI] optimal blocksize for I/O */
st_flags uint32 /* user defined flags for file */
st_gen uint32 /* file generation number */
st_lspare int32 /* RESERVED: DO NOT USE! */
st_qspare [2]int64 /* RESERVED: DO NOT USE! */
}
but in practice it turns out st_size has an offset of 96 bytes instead of the 60 shown above. What's the cause of this discrepancy and how can this be seen from the original source code?
On OS X, both fields of struct timespec are long, which is 64-bit in the usual LP64 convention. Therefore, sizeof(struct timespec) == 16 (you can check this yourself), and it is aligned on a 64-bit boundary, giving you an offset of 96 for st_size.

SCSI Inquiry Data

I am new to SCSI Programming and hence sorry for asking basic question. I sent SCSI Inquiry command to a Tape Device through 6 byte CDB
ccb = (Exec_IO_CCB *)( buffer + header_size );
ccb->ccb_length = sizeof(Exec_IO_CCB);
ccb->cam_opcode = 0x1;
ccb->connect_id = 0;
ccb->sense_buf_ptr = (long)(header_size + ccb->ccb_length);
ccb->sense_buf_length = MAX_SENSE_LEN;
ccb->time_out = CAM_TIMEOUT;
ccb->cdb_length = 6;
/* For INQUIRY sets cam_flags and cdb[0] */
ccb->cam_flags = NO_DATA;
ccb->cdb[0] = INQUIRY; /* 0x12 SCSI Opcode for Inquiry Command */
ccb->cdb[1] = 0;
ccb->cdb[2] = 0;
ccb->cdb[3] = 0;
ccb->cdb[4] = 3200;
ccb->cdb[5] = 0;
The SCSI Command is successful . How do i capture the output of INQUIRY command so that i can get
Vendor ID / Product ID ??
I have declared the Execute I/O SCSI buffer as follows
typedef struct {
long ccb_address; /* Address of this CCB */
short ccb_length; /* CAM Control Block Length */
char cam_opcode; /* CAM Operation Code */
char status; /* CAM Status */
long connect_id; /* Connect ID - no fields supported */
long cam_flags; /* CAM Flags */
long pd_pointer; /* Peripheral driver pointer */
long next_ccb_ptr; /* Next CCB Pointer */
long req_map_info; /* Request mapping information */
long call_on_comp; /* Callback on completion */
long data_buf_ptr; /* Data Buffer Pointer */
long data_xfer_length; /* Data transfer length */
long sense_buf_ptr; /* Sense information buffer pointer */
char sense_buf_length; /* Sense information buffer length */
char cdb_length; /* Command Descriptor Block (CDB) **
** length */
short num_sg_entries; /* Number of scatter/gather entries */
long vendor_unique; /* Vendor Unique field */
char scsi_status; /* SCSI status */
char auto_resid; /* Auto sense residual length */
short reserved; /* Reserved */
long resid_length; /* Residual length */
char cdb[12]; /* Command Descriptor Block (CDB) */
long time_out; /* Time-out value */
long msg_buf_ptr; /* Message buffer pointer */
short msg_buf_length; /* Message buffer length */
short vu_flags; /* Vendor-unique flags */
char tag_queue_act; /* Tagged Queue action */
char tag_id; /* Tag ID (target only) */
char init_id; /* Initiator ID (target only) */
char reserved2; /* Reserved */
} Exec_IO_CCB;
This structure will never capture SCSI Output ?
I have declared the Inquiry Structure as follows . But I am not sure how Inquire command will
populate Inquiry_Data structure data ??
typedef struct {
short data_valid; /* Flag that indicates whether or not the */
/* structure has been filled in with */
/* inquiry data from the device. */
byte periph_qual;
byte periph_dev_type;
byte rmb;
byte iso_version;
byte ecma_version;
byte ansi_version;
byte resp_data_format;
byte rel_adr;
byte sync;
byte linked;
byte cmd_que;
byte sft_rst;
char vendor_id[9];
char prod_id[17];
char prod_rev[5];
char reserved;
} Inquiry_Data;
The first thing that you have assigned a short to cdb[4], but cdb[4] is a byte. The assignment probably put a 0 there since the compiler would truncate. Since bytes 3 and 4 are the allocation length you have told the target not to send anything. Maybe you ment to assign 32 to cdb[4]; but since your Inquiry_Data structure is 44 bytes you probably want to assign 44 to cdb[4].

Segment definitions for linux on x86

Linux 3.4.6 defines the following macros in arch/x86/include/asm/segment.h. Can anybody explain why the __USER macros add 3 to the defined constant and why this is not done for __KERNEL macros?
#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
These four symbols represent segment descriptors. The two least-significant bits of these descriptors contain the privilege level associated with them, and the third least-significant bit contains the descriptor table type (GDT or LDT). This is made clearer by code occurring a little later:
/* User mode is privilege level 3 */
#define USER_RPL 0x3
/* LDT segment has TI set, GDT has it cleared */
#define SEGMENT_LDT 0x4
#define SEGMENT_GDT 0x0
/* Bottom two bits of selector give the ring privilege level */
#define SEGMENT_RPL_MASK 0x3
/* Bit 2 is table indicator (LDT/GDT) */
#define SEGMENT_TI_MASK 0x4
To achieve this, the descriptor table entry is multiplied by 8, which shifts it three bits to the left, and then ORed with the table type and privilege level (using addition):
/* GDT, ring 0 (kernel mode) */
#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
/* GDT, ring 3 (user mode) */
#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)

Can't debug after using SysTick_Config

I - an embedded beginner - am fighting my way through the black magic world of embedded programming. So far I won already a bunch of fights, but this new bug seems to be a hard one.
First, my embedded setup:
Olimex STM32-P207 (STM32F207)
Olimex ARM-USB-OCD-H JTAG
OpenOCD
Eclipse (with CDT and GDB hardware debugging)
Codesourcery Toolchain
Startup file and linker script (adapted memory map for the STM32F207) for RIDE (what uses GCC)
STM32F2xx_StdPeriph_Lib_V1.1.0
Using the many tutorials and Q&As out there I was able to set-up makefile, linker and startup code and got some simple examples running using STM's standard library (classic blinky, using buttons and interrupts etc.). However, once I started playing around with the SysTick interrupts, things got messy.
If add the SysTick_Config() call to my code (even with an empty SysTick_Handler), ...
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
[...]
*/
if (SysTick_Config(SystemCoreClock / 120000))
{
// Catch config error
while(1);
}
[...]
... then my debugger starts at the (inline) function NVIC_SetPriority() and once I hit "run" I end up in the HardFault_Handler().
This only happens, when using the debugger. Otherwise the code runs normal (telling from the blinking LEDs).
I already read a lot and tried a lot (modifying compiler options, linker, startup, trying other code with SysTick_Config() calls), but nothing solved this problem.
One thing could be a hint:
The compiler starts in both cases (with and without the SysTick_Config call) at 0x00000184. In the case without the SysTick_Config call this points at the beginnig of main(). Using SysTick_Config this pionts at NVIC_SetPriority().
Does anybody have a clue what's going on? Any hint about where I could continue my search for a solution?
I don't know what further information would be helpful to solve this riddle. Please let me know and I will be happy to provide the missing pieces.
Thanks a lot!
/edit1: Added results of arm-none-eabi-readelf, -objdump and -size.
/edit2: I removed the code info to make space for the actual code. With this new simplified version debugging starts at
08000184: stmdaeq r0, {r4, r6, r8, r9, r10, r11, sp}
readelf:
[ 2] .text PROGBITS 08000184 008184 002dcc 00 AX 0 0 4
...
2: 08000184 0 SECTION LOCAL DEFAULT 2
...
46: 08000184 0 NOTYPE LOCAL DEFAULT 2 $d
main.c
/* Includes ------------------------------------------------------------------*/
#include "stm32f2xx.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint16_t counter = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void assert_failed(uint8_t* file, uint32_t line);
void Delay(__IO uint32_t nCount);
void SysTick_Handler(void);
/**
* #brief Main program
* #param None
* #retval None
*/
int main(void)
{
if (SysTick_Config(SystemCoreClock / 12000))
{
// Catch config error
while(1);
}
/*
* Configure the LEDs
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); // LEDs
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIOF->BSRRL = GPIO_Pin_6;
while (1)
{
if (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_9) == SET)
{
GPIOF->BSRRH = GPIO_Pin_9;
}
else
{
GPIOF->BSRRL = GPIO_Pin_9;
}
Delay(500000);
}
return 0;
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* #brief Delay Function.
* #param nCount:specifies the Delay time length.
* #retval None
*/
void Delay(__IO uint32_t nCount)
{
while (nCount > 0)
{
nCount--;
}
}
/**
* #brief This function handles Hard Fault exception.
* #param None
* #retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
/**
* #brief This function handles SysTick Handler.
* #param None
* #retval None
*/
void SysTick_Handler(void)
{
if (counter > 10000 )
{
if (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_8) == SET)
{
GPIOF->BSRRH = GPIO_Pin_8;
}
else
{
GPIOF->BSRRL = GPIO_Pin_8;
}
counter = 0;
}
else
{
counter++;
}
}
/edit3:
Soultion:
Because the solution is burrowed in a comment, I put it up here:
My linker file was missing ENTRY(your_function_of_choice); (e.g. Reset_Handler). Adding this made my debugger work again (it now starts at the right point).
Thanks everybody!
I have a strong feeling that the entry point isn't specified correctly in the compiler options or linker script...
And whatever code comes first at link time in the ".text" section, it gets to have the entry point.
The entry point, however, should point to a special "init" function that would set up the stack, initialize the ".bss" section (and maybe some other sections as well), initialize any hardware that's necessary for basic operation (e.g. the interrupt controller and maybe some system timer) and any remaining portions of the and standard libraries before actually transferring control to main().
I'm not familiar with the tools and your hardware, so I can't say exactly what that special "init" function is, but that's pretty much the problem. It's not being pointed to by the entry point of the compiled program. NVIC_SetPriority() doesn't make any sense there.

Resources