Commit b4ec0368 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20041015 from Bob Moore

Signed-off-by: default avatarLen Brown <len.brown@intel.com>

Note: ACPI CA is currently undergoing an in-depth and
complete formal evaluation to test/verify the following
areas. Other suggestions are welcome. This will result in
an increase in the frequency of releases and the number
of bug fixes in the next few months.

- Functional tests for all ASL/AML operators
- All implicit/explicit type conversions
- Bit fields and operation regions
- 64-bit math support and 32-bit-only "truncated" math support
- Exceptional conditions, both compiler and interpreter
- Dynamic object deletion and memory leaks
- ACPI 3.0 support when implemented
- External interfaces to the ACPI subsystem

Fixed two alignment issues on 64-bit platforms -
within debug statements in acpi_ev_gpe_detect and
acpi_ev_create_gpe_block. Removed references to the
Address field within the non-aligned ACPI generic address
structure.

Fixed a problem in the Increment and Decrement operators
where incorrect operand resolution could result in the
inadvertent modification of the original integer when the
integer is passed into another method as an argument and
the arg is then incremented/decremented.

Fixed a problem in the FromBCD operator where the upper
32-bits of a 64-bit BCD number were truncated during
conversion.

Fixed a problem in the ToDecimal operator where the length
of the resulting string could be set incorrectly too long
if the input operand was a Buffer object.

Fixed a problem in the Logical operators (LLess,
etc.) where a NULL byte (0) within a buffer would
prematurely terminate a compare between buffer objects.

Added a check for string overflow (>200 characters as per
the ACPI specification) during the Concatenate operator
with two string operands.
parent ee82c878
......@@ -312,7 +312,7 @@ acpi_ds_method_data_set_value (
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"obj %p op %X, ref count = %d [%s]\n", object,
"new_obj %p Opcode %X, Refs=%d [%s]\n", object,
opcode, object->common.reference_count,
acpi_ut_get_type_name (object->common.type)));
......@@ -572,7 +572,7 @@ acpi_ds_store_object_to_local (
ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
opcode, index, obj_desc));
/* Parameter validation */
......
......@@ -333,7 +333,7 @@ acpi_ds_clear_operands (
u32 i;
ACPI_FUNCTION_TRACE_PTR ("acpi_ds_clear_operands", walk_state);
ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
/*
......
......@@ -434,13 +434,8 @@ acpi_ev_gpe_detect (
}
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
ACPI_FORMAT_UINT64 (
gpe_register_info->status_address.address),
status_reg,
ACPI_FORMAT_UINT64 (
gpe_register_info->enable_address.address),
enable_reg));
"Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
gpe_register_info->base_gpe_number, status_reg, enable_reg));
/* First check if there is anything active at all in this register */
......
......@@ -970,16 +970,14 @@ acpi_ev_create_gpe_block (
/* Dump info about this GPE block */
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
"GPE %02X to %02X [%4.4s] %u regs at %8.8X%8.8X on int 0x%X\n",
"GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
(u32) gpe_block->block_base_number,
(u32) (gpe_block->block_base_number +
((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
gpe_device->name.ascii,
gpe_block->register_count,
ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
interrupt_level));
/* Enable all valid GPEs found above */
status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block);
......
......@@ -437,9 +437,9 @@ acpi_ex_convert_to_string (
/*
* Create a new String
* Need enough space for one ASCII integer plus null terminator
* Need enough space for one ASCII integer (plus null terminator)
*/
return_desc = acpi_ut_create_string_object ((acpi_size) string_length + 1);
return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......@@ -495,7 +495,7 @@ acpi_ex_convert_to_string (
/* Create a new string object and string buffer */
return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
return_desc = acpi_ut_create_string_object ((acpi_size) string_length -1);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......@@ -517,6 +517,10 @@ acpi_ex_convert_to_string (
new_buf--;
*new_buf = 0;
/* Recalculate length */
return_desc->string.length = ACPI_STRLEN (return_desc->string.pointer);
break;
default:
......
......@@ -244,6 +244,7 @@ acpi_ex_do_concatenate (
union acpi_operand_object *return_desc;
char *new_buf;
acpi_status status;
acpi_size new_length;
ACPI_FUNCTION_TRACE ("ex_do_concatenate");
......@@ -325,9 +326,14 @@ acpi_ex_do_concatenate (
/* Result of two Strings is a String */
return_desc = acpi_ut_create_string_object (
(acpi_size) operand0->string.length +
(acpi_size) local_operand1->string.length + 1);
new_length = (acpi_size) operand0->string.length +
(acpi_size) local_operand1->string.length;
if (new_length > ACPI_MAX_STRING_CONVERSION) {
status = AE_AML_STRING_LIMIT;
goto cleanup;
}
return_desc = acpi_ut_create_string_object (new_length);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
......@@ -649,14 +655,15 @@ acpi_ex_do_logical_op (
/*
* 2) Both operands are Strings or both are Buffers
* Note: Code below takes advantage of common Buffer/String
* object fields. local_operand1 may have changed above
* object fields. local_operand1 may have changed above. Use
* memcmp to handle nulls in buffers.
*/
length0 = operand0->buffer.length;
length1 = local_operand1->buffer.length;
/* Lexicographic compare: compare the data bytes */
compare = ACPI_STRNCMP ((const char * ) operand0->buffer.pointer,
compare = ACPI_MEMCMP ((const char * ) operand0->buffer.pointer,
(const char * ) local_operand1->buffer.pointer,
(length0 > length1) ? length1 : length0);
......
......@@ -285,7 +285,7 @@ acpi_ex_opcode_1A_1T_1R (
union acpi_operand_object *return_desc2 = NULL;
u32 temp32;
u32 i;
u32 power_of_ten;
acpi_integer power_of_ten;
acpi_integer digit;
......@@ -325,7 +325,8 @@ acpi_ex_opcode_1A_1T_1R (
* Acpi specification describes Integer type as a little
* endian unsigned value, so this boundary condition is valid.
*/
for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
for (temp32 = 0; return_desc->integer.value &&
temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
return_desc->integer.value >>= 1;
}
......@@ -341,13 +342,15 @@ acpi_ex_opcode_1A_1T_1R (
* The Acpi specification describes Integer type as a little
* endian unsigned value, so this boundary condition is valid.
*/
for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
for (temp32 = 0; return_desc->integer.value &&
temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
return_desc->integer.value <<= 1;
}
/* Since the bit position is one-based, subtract from 33 (65) */
return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
return_desc->integer.value = temp32 == 0 ? 0 :
(ACPI_INTEGER_BIT_SIZE + 1) - temp32;
break;
......@@ -382,7 +385,8 @@ acpi_ex_opcode_1A_1T_1R (
/* Sum the digit into the result with the current power of 10 */
return_desc->integer.value += (((acpi_integer) temp32) * power_of_ten);
return_desc->integer.value += (((acpi_integer) temp32) *
power_of_ten);
/* Shift to next BCD digit */
......@@ -407,13 +411,15 @@ acpi_ex_opcode_1A_1T_1R (
/* Insert the BCD digit that resides in the remainder from above */
return_desc->integer.value |= (((acpi_integer) temp32) << ACPI_MUL_4 (i));
return_desc->integer.value |= (((acpi_integer) temp32) <<
ACPI_MUL_4 (i));
}
/* Overflow if there is any data left in Digit */
if (digit > 0) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Integer too large to convert to BCD: %8.8X%8.8X\n",
ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
status = AE_AML_NUMERIC_OVERFLOW;
goto cleanup;
......@@ -619,41 +625,61 @@ acpi_ex_opcode_1A_0T_1R (
case AML_INCREMENT_OP: /* Increment (Operand) */
/*
* Since we are expecting a Reference operand, it
* can be either a NS Node or an internal object.
* Create a new integer. Can't just get the base integer and
* increment it because it may be an Arg or Field.
*/
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
/*
* Since we are expecting a Reference operand, it can be either a
* NS Node or an internal object.
*/
return_desc = operand[0];
if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_OPERAND) {
temp_desc = operand[0];
if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) {
/* Internal reference object - prevent deletion */
acpi_ut_add_reference (return_desc);
acpi_ut_add_reference (temp_desc);
}
/*
* Convert the return_desc Reference to a Number
* (This removes a reference on the return_desc object)
* Convert the Reference operand to an Integer (This removes a
* reference on the Operand[0] object)
*
* NOTE: We use LNOT_OP here in order to force resolution of the
* reference operand to an actual integer.
*/
status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state);
status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status)));
acpi_ps_get_opcode_name (walk_state->opcode),
acpi_format_exception(status)));
goto cleanup;
}
/*
* return_desc is now guaranteed to be an Integer object
* Do the actual increment or decrement
* temp_desc is now guaranteed to be an Integer object --
* Perform the actual increment or decrement
*/
if (AML_INCREMENT_OP == walk_state->opcode) {
return_desc->integer.value++;
if (walk_state->opcode == AML_INCREMENT_OP) {
return_desc->integer.value = temp_desc->integer.value +1;
}
else {
return_desc->integer.value--;
return_desc->integer.value = temp_desc->integer.value -1;
}
/* Store the result back in the original descriptor */
/* Finished with this Integer object */
acpi_ut_remove_reference (temp_desc);
/*
* Store the result back (indirectly) through the original
* Reference object
*/
status = acpi_ex_store (return_desc, operand[0], walk_state);
break;
......@@ -707,7 +733,8 @@ acpi_ex_opcode_1A_0T_1R (
break;
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "size_of, Not Buf/Str/Pkg - found type %s\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"size_of, Not Buf/Str/Pkg - found type %s\n",
acpi_ut_get_type_name (type)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
......@@ -877,7 +904,8 @@ acpi_ex_opcode_1A_0T_1R (
* an uninitialized package element and is thus a
* severe error.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"NULL package element obj %p\n",
operand[0]));
status = AE_AML_UNINITIALIZED_ELEMENT;
goto cleanup;
......@@ -889,7 +917,8 @@ acpi_ex_opcode_1A_0T_1R (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index target_type %X in obj %p\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown Index target_type %X in obj %p\n",
operand[0]->reference.target_type, operand[0]));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
......@@ -913,7 +942,8 @@ acpi_ex_opcode_1A_0T_1R (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown opcode in ref(%p) - %X\n",
operand[0], operand[0]->reference.opcode));
status = AE_TYPE;
......
......@@ -375,9 +375,9 @@ acpi_ex_opcode_2A_1T_1R (
}
}
/* Allocate a new string (Length + 1 for null terminator) */
/* Allocate a new string object */
return_desc = acpi_ut_create_string_object (length + 1);
return_desc = acpi_ut_create_string_object (length);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
......
......@@ -160,7 +160,7 @@ acpi_ex_resolve_operands (
return_ACPI_STATUS (AE_AML_INTERNAL);
}
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] operand_types=%X \n",
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n",
opcode, op_info->name, arg_types));
/*
......@@ -227,12 +227,13 @@ acpi_ex_resolve_operands (
case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Reference Opcode: %s\n", op_info->name)));
"Operand is a Reference, ref_opcode [%s]\n",
(acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)));
break;
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown Reference Opcode %X [%s]\n",
"Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
obj_desc->reference.opcode,
(acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name));
......
......@@ -129,7 +129,8 @@ acpi_ex_store (
/* Destination is not a Reference object */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Destination is not a Reference or Constant object [%p]\n", dest_desc));
"Target is not a Reference or Constant object - %s [%p]\n",
acpi_ut_get_object_type_name (dest_desc), dest_desc));
ACPI_DUMP_STACK_ENTRY (source_desc);
ACPI_DUMP_STACK_ENTRY (dest_desc);
......@@ -182,11 +183,19 @@ acpi_ex_store (
* Storing to the Debug object causes the value stored to be
* displayed and otherwise has no effect -- see ACPI Specification
*/
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"**** Write to Debug Object: Object %p %s ****:\n\n",
source_desc, acpi_ut_get_object_type_name (source_desc)));
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
acpi_ut_get_object_type_name (source_desc)));
if (!acpi_ut_valid_internal_object (source_desc)) {
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
"%X, Invalid Internal Object!\n", source_desc));
break;
}
switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
case ACPI_TYPE_INTEGER:
......
......@@ -727,7 +727,7 @@ acpi_hw_low_level_read (
/* Get a local copy of the address. Handles possible alignment issues */
address = ACPI_MOVE_64_TO_64 (&address, &reg->address);
ACPI_MOVE_64_TO_64 (&address, &reg->address);
if (!address) {
return (AE_OK);
}
......@@ -806,7 +806,7 @@ acpi_hw_low_level_write (
/* Get a local copy of the address. Handles possible alignment issues */
address = ACPI_MOVE_64_TO_64 (&address, &reg->address);
ACPI_MOVE_64_TO_64 (&address, &reg->address);
if (!address) {
return (AE_OK);
}
......
......@@ -731,7 +731,7 @@ acpi_ps_get_opcode_info (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown extended opcode [%X]\n", opcode));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode [%4.4X]\n", opcode));
break;
}
......
......@@ -192,9 +192,9 @@ acpi_ut_create_buffer_object (
*
* FUNCTION: acpi_ut_create_string_object
*
* PARAMETERS: string_size - Size of string to be created, plus one
* for the NULL terminater. Actual sting
* length will be this size minus one.
* PARAMETERS: string_size - Size of string to be created. Does not
* include NULL terminator, this is added
* automatically.
*
* RETURN: Pointer to a new String object
*
......@@ -207,7 +207,7 @@ acpi_ut_create_string_object (
acpi_size string_size)
{
union acpi_operand_object *string_desc;
char *string = NULL;
char *string;
ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
......@@ -220,24 +220,22 @@ acpi_ut_create_string_object (
return_PTR (NULL);
}
/* Create an actual string only if size > 0 */
if (string_size > 0) {
/* Allocate the actual string */
string = ACPI_MEM_CALLOCATE (string_size);
/*
* Allocate the actual string buffer -- (Size + 1) for NULL terminator.
* NOTE: Zero-length strings are NULL terminated
*/
string = ACPI_MEM_CALLOCATE (string_size + 1);
if (!string) {
ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
(u32) string_size));
acpi_ut_remove_reference (string_desc);
return_PTR (NULL);
}
}
/* Complete string object initialization */
string_desc->string.pointer = string;
string_desc->string.length = (u32) string_size - 1;
string_desc->string.length = (u32) string_size;
/* Return the new string descriptor */
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20041006
#define ACPI_CA_VERSION 0x20041015
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......
......@@ -177,6 +177,12 @@ acpi_ut_strncpy (
const char *src_string,
acpi_size count);
int
acpi_ut_memcmp (
const char *buffer1,
const char *buffer2,
acpi_size count);
int
acpi_ut_strncmp (
const char *string1,
......
......@@ -232,6 +232,7 @@
#define ACPI_STRCAT(d,s) (void) strcat((d), (s))
#define ACPI_STRNCAT(d,s,n) strncat((d), (s), (acpi_size)(n))
#define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (acpi_size)(n))
#define ACPI_MEMCMP(s1,s2,n) memcmp((s1), (s2), (acpi_size)(n))
#define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n))
#define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n))
......@@ -295,6 +296,7 @@ typedef char *va_list;
#define ACPI_STRCAT(d,s) (void) acpi_ut_strcat ((d), (s))
#define ACPI_STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (acpi_size)(n))
#define ACPI_STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s), (acpi_size)(n))
#define ACPI_MEMCMP(s1,s2,n) acpi_ut_memcmp((s1), (s2), (acpi_size)(n))
#define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n))
#define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n))
#define ACPI_TOUPPER acpi_ut_to_upper
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment